UNPKG

cdk-sops-secrets

Version:

CDK Constructs that syncs your sops secrets into AWS SecretsManager secrets.

253 lines (252 loc) • 9.68 kB
import { SecretValue } from 'aws-cdk-lib'; import { ISecurityGroup, IVpc, SubnetSelection } from 'aws-cdk-lib/aws-ec2'; import { IGrantable, IRole } from 'aws-cdk-lib/aws-iam'; import { IKey } from 'aws-cdk-lib/aws-kms'; import { SingletonFunction } from 'aws-cdk-lib/aws-lambda'; import { RetentionDays, ILogGroup } from 'aws-cdk-lib/aws-logs'; import { Asset } from 'aws-cdk-lib/aws-s3-assets'; import { ISecret } from 'aws-cdk-lib/aws-secretsmanager'; import { IStringParameter } from 'aws-cdk-lib/aws-ssm'; import { Construct } from 'constructs'; export declare enum UploadType { /** * Pass the secret data inline (base64 encoded and compressed) */ INLINE = "INLINE", /** * Uplaod the secret data as asset */ ASSET = "ASSET" } export declare enum ResourceType { SECRET = "SECRET", SECRET_RAW = "SECRET_RAW", SECRET_BINARY = "SECRET_BINARY", PARAMETER = "PARAMETER", PARAMETER_MULTI = "PARAMETER_MULTI" } /** * Configuration options for the SopsSync */ export interface SopsSyncOptions { /** * The custom resource provider to use. If you don't specify any, a new * provider will be created - or if already exists within this stack - reused. * * @default - A new singleton provider will be created */ readonly sopsProvider?: SopsSyncProvider; /** * The filepath to the sops file */ readonly sopsFilePath?: string; /** * If you want to pass the sops file via s3, you can specify the bucket * you can use cfn parameter here * Both, sopsS3Bucket and sopsS3Key have to be specified */ readonly sopsS3Bucket?: string; /** * If you want to pass the sops file via s3, you can specify the key inside the bucket * you can use cfn parameter here * Both, sopsS3Bucket and sopsS3Key have to be specified */ readonly sopsS3Key?: string; /** * How should the secret be passed to the CustomResource? * @default INLINE */ readonly uploadType?: UploadType; /** * The format of the sops file. * * @default - The fileformat will be derived from the file ending */ readonly sopsFileFormat?: undefined | 'json' | 'yaml' | 'dotenv' | 'binary'; /** * The kmsKey used to encrypt the sops file. Encrypt permissions * will be granted to the custom resource provider. * * @default - The key will be derived from the sops file */ readonly sopsKmsKey?: IKey[]; /** * The age key that should be used for encryption. */ readonly sopsAgeKey?: SecretValue; /** * Should this construct automatically create IAM permissions? * * @default true */ readonly autoGenerateIamPermissions?: boolean; /** * The encryption key used by the CDK default Asset S3 Bucket. * @default - Trying to get the key using the CDK Bootstrap context. */ readonly assetEncryptionKey?: IKey; } /** * The configuration options extended by the target Secret / Parameter */ export interface SopsSyncProps extends SopsSyncOptions { /** * The target to populate with the sops file content. * - for secret, it's the name or arn of the secret * - for parameter, it's the name of the parameter * - for parameter multi, it's the prefix of the parameters */ readonly target: string; /** * If the structure should be flattened use the provided separator between keys. * * @default - undefined */ readonly flattenSeparator?: string; /** * The encryption key used for encrypting the ssm parameter if `parameterName` is set. */ readonly encryptionKey?: IKey; /** * Will this Sync deploy a Secret or Parameter(s) */ readonly resourceType: ResourceType; readonly secret?: ISecret; readonly parameterNames?: string[]; } /** * Configuration options for a custom SopsSyncProvider. */ export interface SopsSyncProviderProps { /** * VPC network to place Lambda network interfaces. * * @default - Lambda function is not placed within a VPC. */ readonly vpc?: IVpc; /** * Where to place the network interfaces within the VPC. * * @default - Subnets will be chosen automatically. */ readonly vpcSubnets?: SubnetSelection; /** * Only if `vpc` is supplied: The list of security groups to associate with the Lambda's network interfaces. * * @default - A dedicated security group will be created for the lambda function. */ readonly securityGroups?: ISecurityGroup[]; /** * The role that should be used for the custom resource provider. * If you don't specify any, a new role will be created with all required permissions * * @default - a new role will be created */ readonly role?: IRole; /** * The number of days log events are kept in CloudWatch Logs. When updating * this property, unsetting it doesn't remove the log retention policy. To * remove the retention policy, set the value to `INFINITE`. * * This is a legacy API and we strongly recommend you move away from it if you can. * Instead create a fully customizable log group with `logs.LogGroup` and use the `logGroup` property * to instruct the Lambda function to send logs to it. * Migrating from `logRetention` to `logGroup` will cause the name of the log group to change. * Users and code and referencing the name verbatim will have to adjust. * * In AWS CDK code, you can access the log group name directly from the LogGroup construct: * ```ts * import * as logs from 'aws-cdk-lib/aws-logs'; * * declare const myLogGroup: logs.LogGroup; * myLogGroup.logGroupName; * ``` * * @default logs.RetentionDays.INFINITE */ readonly logRetention?: RetentionDays; /** * The log group the function sends logs to. * * By default, Lambda functions send logs to an automatically created default log group named /aws/lambda/{function-name}. * However you cannot change the properties of this auto-created log group using the AWS CDK, e.g. you cannot set a different log retention. * * Use the `logGroup` property to create a fully customizable LogGroup ahead of time, and instruct the Lambda function to send logs to it. * * Providing a user-controlled log group was rolled out to commercial regions on 2023-11-16. * If you are deploying to another type of region, please check regional availability first. * * @default `/aws/lambda/${this.functionName}` - default log group created by Lambda */ readonly logGroup?: ILogGroup; /** * A unique identifier to identify this provider * * Overwrite the default, if you need a dedicated provider. * * @default SopsSyncProvider */ readonly uuid?: string; } export declare class SopsSyncProvider extends SingletonFunction implements IGrantable { private sopsAgeKeys; private sopsAgeKeyParams; constructor(scope: Construct, id?: string, props?: SopsSyncProviderProps); addAgeKey(key: SecretValue): void; /** * Configure the Lambda to fetch an age private key from an SSM Parameter * Store SecureString at runtime, rather than injecting it as a plaintext * environment variable at synthesis time. * * The KMS key used to encrypt the SecureString is required: storing an age * private key without envelope encryption is considered insecure. * * The Lambda is automatically granted `ssm:GetParameter` on the parameter * and `kms:Decrypt` on the encryption key. * * @param param Parameter name string (e.g. '/sops/age/key') or an * `IStringParameter` reference from `aws-cdk-lib/aws-ssm`. * @param encryptionKey KMS key used to encrypt the SecureString parameter. */ addAgeKeyFromSsmParameter(param: string | IStringParameter, encryptionKey: IKey): void; } /** * The custom resource, that is syncing the content from a sops file to a secret. */ export declare class SopsSync extends Construct { /** * The current versionId of the secret populated via this resource */ readonly versionId: string; constructor(scope: Construct, id: string, props: SopsSyncProps); } export declare namespace Permissions { /** * Grants the necessary permissions for encrypt/decrypt on the customer managed encryption key * for the secrets / parameters. */ function encryptionKey(key: IKey | undefined, target: IGrantable): void; function keysFromSopsContent(ctx: Construct, c: string): IKey[]; function keysFromSopsContentAlias(ctx: Construct, c: string): IKey[]; /** * Grants the necessary permissions to decrypt the given sops file content. * Takes user defined keys, and searches the sops file for keys and aliases. */ function sopsKeys(ctx: Construct, props: { userDefinedKeys?: IKey[]; sopsFileContent: string; role: IRole; }): void; /** * Grants the necessary permissions to write the given secrets. */ function secret(targetSecret: ISecret | undefined, target: IGrantable): void; /** * Grants the necessary permissions to write the given parameters. */ function parameters(ctx: Construct, targetParameters: string[] | undefined, role: IRole): void; /** * Grants the necessary permissions to read the given asset from S3. */ function assetBucket(context: Construct, asset: Asset | undefined, target: IGrantable, assetKey: IKey | undefined): void; }