From 4439dbf0f8b50a0a9d580a781de67789e5ad8adc Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Fri, 6 Sep 2024 16:08:51 +1000 Subject: [PATCH 1/7] Add the option to create a KMS key for signing of pipelines --- templates/aws-stack.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/templates/aws-stack.yml b/templates/aws-stack.yml index b7517ae4e..0ed56a020 100644 --- a/templates/aws-stack.yml +++ b/templates/aws-stack.yml @@ -568,6 +568,14 @@ Parameters: Description: Optional - Customise the EC2 instance Name tag Default: "" + PipelineSigningKMSKeySpec: + Type: String + Description: The key spec for the KMS key used to sign and verify pipelines + AllowedValues: + - "ECC_NIST_P256" + - "none" + Default: "none" + Rules: HasToken: Assertions: @@ -685,6 +693,9 @@ Conditions: UseCostAllocationTags: !Equals [ !Ref EnableCostAllocationTags, "true" ] + + CreatePipelineSigningKMSKey: + !Not [ !Equals [ !Ref PipelineSigningKMSKeySpec, "none" ] ] HasKeyName: !Not [ !Equals [ !Ref KeyName, "" ] ] @@ -871,6 +882,17 @@ Resources: Name: !Sub "/${AWS::StackName}/buildkite/agent-token" Type: String Value: !Ref BuildkiteAgentToken + + PipelineSigningKMSKey: + Type: AWS::KMS::Key + Condition: CreatePipelineSigningKMSKey + Properties: + Description: Key used to sign and verify pipelines + KeySpec: !Ref PipelineSigningKMSKeySpec + KeyUsage: SIGN_VERIFY + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-PipelineSigningKey' # Allow ec2 instances to assume a role and be granted the IAMPolicies IAMInstanceProfile: @@ -1231,6 +1253,7 @@ Resources: $Env:BUILDKITE_QUEUE="${BuildkiteQueue}" $Env:BUILDKITE_AGENT_ENABLE_GIT_MIRRORS="${BuildkiteAgentEnableGitMirrors}" $Env:BUILDKITE_ELASTIC_BOOTSTRAP_SCRIPT="${BootstrapScriptUrl}" + $Env:BUILDKITE_AGENT_SIGNING_KMS_KEY="${PipelineSigningKMSKey}" $Env:BUILDKITE_ENV_FILE_URL="${AgentEnvFileUrl}" $Env:BUILDKITE_AUTHORIZED_USERS_URL="${AuthorizedUsersUrl}" $Env:BUILDKITE_ECR_POLICY="${ECRAccessPolicy}" @@ -1248,6 +1271,7 @@ Resources: LocalSecretsBucket: !If [ CreateSecretsBucket, !Ref ManagedSecretsBucket, !Ref SecretsBucket ], LocalSecretsBucketRegion: !If [ CreateSecretsBucket, !Ref "AWS::Region", !Ref SecretsBucketRegion ], AgentTokenPath: !If [ UseCustomerManagedParameterPath, !Ref BuildkiteAgentTokenParameterStorePath, !Ref BuildkiteAgentTokenParameter ], + PipelineSigningKMSKey: !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, "" ], } - !Sub - | @@ -1288,6 +1312,7 @@ Resources: BUILDKITE_AGENT_TRACING_BACKEND="${BuildkiteAgentTracingBackend}" \ BUILDKITE_AGENT_RELEASE="${BuildkiteAgentRelease}" \ BUILDKITE_AGENT_CANCEL_GRACE_PERIOD="${BuildkiteAgentCancelGracePeriod}" \ + BUILDKITE_AGENT_SIGNING_KMS_KEY="${PipelineSigningKMSKey}" \ BUILDKITE_QUEUE="${BuildkiteQueue}" \ BUILDKITE_AGENT_ENABLE_GIT_MIRRORS="${BuildkiteAgentEnableGitMirrors}" \ BUILDKITE_ELASTIC_BOOTSTRAP_SCRIPT="${BootstrapScriptUrl}" \ @@ -1310,6 +1335,7 @@ Resources: LocalSecretsBucket: !If [ CreateSecretsBucket, !Ref ManagedSecretsBucket, !Ref SecretsBucket ], LocalSecretsBucketRegion: !If [ CreateSecretsBucket, !Ref "AWS::Region", !Ref SecretsBucketRegion ], AgentTokenPath: !If [ UseCustomerManagedParameterPath, !Ref BuildkiteAgentTokenParameterStorePath, !Ref BuildkiteAgentTokenParameter ], + PipelineSigningKMSKey: !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, "" ], } AgentAutoScaleGroup: From 9d2e9021bb8a1da125889a180ff061510bca258f Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Fri, 6 Sep 2024 16:19:59 +1000 Subject: [PATCH 2/7] Add the configuration to the agent for the optional kms siging key --- packer/linux/conf/bin/bk-install-elastic-stack.sh | 1 + packer/windows/conf/bin/bk-install-elastic-stack.ps1 | 1 + 2 files changed, 2 insertions(+) diff --git a/packer/linux/conf/bin/bk-install-elastic-stack.sh b/packer/linux/conf/bin/bk-install-elastic-stack.sh index 70fa77cda..126ca89c3 100755 --- a/packer/linux/conf/bin/bk-install-elastic-stack.sh +++ b/packer/linux/conf/bin/bk-install-elastic-stack.sh @@ -291,6 +291,7 @@ disconnect-after-idle-timeout=${BUILDKITE_SCALE_IN_IDLE_PERIOD} disconnect-after-job=${BUILDKITE_TERMINATE_INSTANCE_AFTER_JOB} tracing-backend=${BUILDKITE_AGENT_TRACING_BACKEND} cancel-grace-period=${BUILDKITE_AGENT_CANCEL_GRACE_PERIOD} +signing-jwks-key-id=${BUILDKITE_AGENT_SIGNING_KMS_KEY} EOF if [[ "${BUILDKITE_ENV_FILE_URL}" != "" ]]; then diff --git a/packer/windows/conf/bin/bk-install-elastic-stack.ps1 b/packer/windows/conf/bin/bk-install-elastic-stack.ps1 index de2856c7d..0cb6cd2aa 100644 --- a/packer/windows/conf/bin/bk-install-elastic-stack.ps1 +++ b/packer/windows/conf/bin/bk-install-elastic-stack.ps1 @@ -147,6 +147,7 @@ shell=powershell disconnect-after-idle-timeout=${Env:BUILDKITE_SCALE_IN_IDLE_PERIOD} disconnect-after-job=${Env:BUILDKITE_TERMINATE_INSTANCE_AFTER_JOB} tracing-backend=${Env:BUILDKITE_AGENT_TRACING_BACKEND} +signing-jwks-key-id=${Env:BUILDKITE_AGENT_SIGNING_KMS_KEY} "@ $OFS=" " From 38bc536f5f84031200bbc1364d6e58db3f2b5237 Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Fri, 6 Sep 2024 16:47:28 +1000 Subject: [PATCH 3/7] Update the agent policy to grant access to signing kms key if present --- templates/aws-stack.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/templates/aws-stack.yml b/templates/aws-stack.yml index 0ed56a020..a64dd8bbb 100644 --- a/templates/aws-stack.yml +++ b/templates/aws-stack.yml @@ -925,6 +925,19 @@ Resources: - !Ref 'AWS::NoValue' - !Ref 'AWS::NoValue' Policies: + - !If + - CreatePipelineSigningKMSKey + - PolicyName: PipelineSigningKMSKeyAccess + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - kms:GetPublicKey + - kms:Sign + - kms:Verify + Resource: !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKey} + - !Ref 'AWS::NoValue' - !If - UseCustomerManagedKeyForParameterStore - PolicyName: DecryptAgentToken From e4cd1c7d42349dd856e2be8f6993a5ed8e33cd61 Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Tue, 10 Sep 2024 12:23:36 +1000 Subject: [PATCH 4/7] Fix configuration of the agent kms signing key --- packer/linux/conf/bin/bk-install-elastic-stack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packer/linux/conf/bin/bk-install-elastic-stack.sh b/packer/linux/conf/bin/bk-install-elastic-stack.sh index 126ca89c3..43d096f08 100755 --- a/packer/linux/conf/bin/bk-install-elastic-stack.sh +++ b/packer/linux/conf/bin/bk-install-elastic-stack.sh @@ -291,7 +291,7 @@ disconnect-after-idle-timeout=${BUILDKITE_SCALE_IN_IDLE_PERIOD} disconnect-after-job=${BUILDKITE_TERMINATE_INSTANCE_AFTER_JOB} tracing-backend=${BUILDKITE_AGENT_TRACING_BACKEND} cancel-grace-period=${BUILDKITE_AGENT_CANCEL_GRACE_PERIOD} -signing-jwks-key-id=${BUILDKITE_AGENT_SIGNING_KMS_KEY} +signing-aws-kms-key=${BUILDKITE_AGENT_SIGNING_KMS_KEY} EOF if [[ "${BUILDKITE_ENV_FILE_URL}" != "" ]]; then From e2b6872c771049feb1e63514713554a668137c6a Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Wed, 11 Sep 2024 09:29:28 +1000 Subject: [PATCH 5/7] Added export of KMS signing key and option to provide a signing key id --- templates/aws-stack.yml | 44 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/templates/aws-stack.yml b/templates/aws-stack.yml index a64dd8bbb..91de26843 100644 --- a/templates/aws-stack.yml +++ b/templates/aws-stack.yml @@ -568,6 +568,11 @@ Parameters: Description: Optional - Customise the EC2 instance Name tag Default: "" + PipelineSigningKMSKeyId: + Type: String + Description: Optional - Identifier of the KMS key used to sign and verify pipelines (Created if left blank and PipelineSigningKMSKeySpec is selected) + Default: "" + PipelineSigningKMSKeySpec: Type: String Description: The key spec for the KMS key used to sign and verify pipelines @@ -590,6 +595,17 @@ Rules: - !Ref BuildkiteAgentTokenParameterStorePath - "" AssertDescription: "You must provide BuildkiteAgentToken or BuildkiteAgentTokenParameterStorePath" + HasPipelineSigningKMSKey: + Assertions: + - Assert: + !Or + - !Equals + - !Ref PipelineSigningKMSKeyId + - "" + - !Equals + - !Ref PipelineSigningKMSKeySpec + - "none" + AssertDescription: "You must provide either provide a PipelineSigningKMSKeyId or select a PipelineSigningKMSKeySpec but not both" Outputs: VpcId: @@ -610,6 +626,12 @@ Outputs: Export: Name: !Sub '${AWS::StackName}-ManagedSecretsLoggingBucket' + PipelineSigningKMSKey: + Value: + !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, "none" ] + Export: + Name: !Sub '${AWS::StackName}-PipelineSigningKMSKey' + AutoScalingGroupName: Value: !Ref AgentAutoScaleGroup Export: @@ -694,8 +716,16 @@ Conditions: UseCostAllocationTags: !Equals [ !Ref EnableCostAllocationTags, "true" ] + UsePipelineSigningKMSKey: + !Not [ !Equals [ !Ref PipelineSigningKMSKeyId, "" ] ] + CreatePipelineSigningKMSKey: - !Not [ !Equals [ !Ref PipelineSigningKMSKeySpec, "none" ] ] + !And + - !Equals [ !Ref PipelineSigningKMSKeyId, "" ] + - !Not [ !Equals [ !Ref PipelineSigningKMSKeySpec, "none" ] ] + + HasPipelineSigningKMSKey: + !Or [ !Condition CreatePipelineSigningKMSKey, !Condition UsePipelineSigningKMSKey ] HasKeyName: !Not [ !Equals [ !Ref KeyName, "" ] ] @@ -886,6 +916,7 @@ Resources: PipelineSigningKMSKey: Type: AWS::KMS::Key Condition: CreatePipelineSigningKMSKey + DeletionPolicy: Retain Properties: Description: Key used to sign and verify pipelines KeySpec: !Ref PipelineSigningKMSKeySpec @@ -926,7 +957,7 @@ Resources: - !Ref 'AWS::NoValue' Policies: - !If - - CreatePipelineSigningKMSKey + - HasPipelineSigningKMSKey - PolicyName: PipelineSigningKMSKeyAccess PolicyDocument: Version: '2012-10-17' @@ -936,7 +967,10 @@ Resources: - kms:GetPublicKey - kms:Sign - kms:Verify - Resource: !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKey} + Resource: !If + - HasPipelineSigningKMSKey + - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKeyId} + - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKey} - !Ref 'AWS::NoValue' - !If - UseCustomerManagedKeyForParameterStore @@ -1284,7 +1318,7 @@ Resources: LocalSecretsBucket: !If [ CreateSecretsBucket, !Ref ManagedSecretsBucket, !Ref SecretsBucket ], LocalSecretsBucketRegion: !If [ CreateSecretsBucket, !Ref "AWS::Region", !Ref SecretsBucketRegion ], AgentTokenPath: !If [ UseCustomerManagedParameterPath, !Ref BuildkiteAgentTokenParameterStorePath, !Ref BuildkiteAgentTokenParameter ], - PipelineSigningKMSKey: !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, "" ], + PipelineSigningKMSKey: !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, !Ref PipelineSigningKMSKeyId ], } - !Sub - | @@ -1348,7 +1382,7 @@ Resources: LocalSecretsBucket: !If [ CreateSecretsBucket, !Ref ManagedSecretsBucket, !Ref SecretsBucket ], LocalSecretsBucketRegion: !If [ CreateSecretsBucket, !Ref "AWS::Region", !Ref SecretsBucketRegion ], AgentTokenPath: !If [ UseCustomerManagedParameterPath, !Ref BuildkiteAgentTokenParameterStorePath, !Ref BuildkiteAgentTokenParameter ], - PipelineSigningKMSKey: !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, "" ], + PipelineSigningKMSKey: !If [ CreatePipelineSigningKMSKey, !Ref PipelineSigningKMSKey, !Ref PipelineSigningKMSKeyId ], } AgentAutoScaleGroup: From 7eec5295cb6d4419a3bbdd3a4872c837f810f910 Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Wed, 11 Sep 2024 12:15:10 +1000 Subject: [PATCH 6/7] Updated signed pipeline options to allow seperate sign and verify queues --- templates/aws-stack.yml | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/templates/aws-stack.yml b/templates/aws-stack.yml index 91de26843..6b02ed5de 100644 --- a/templates/aws-stack.yml +++ b/templates/aws-stack.yml @@ -27,13 +27,20 @@ Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: - default: Buildkite Configuration + default: Base Configuration Parameters: + - BuildkiteAgentToken - BuildkiteAgentTokenParameterStorePath - BuildkiteAgentTokenParameterStoreKMSKey - - BuildkiteAgentToken - BuildkiteQueue + - Label: + default: Signed Pipelines Configuration + Parameters: + - PipelineSigningKMSKeyId + - PipelineSigningKMSKeySpec + - PipelineSigningKMSAccess + - Label: default: Advanced Buildkite Configuration Parameters: @@ -581,6 +588,14 @@ Parameters: - "none" Default: "none" + PipelineSigningKMSAccess: + Type: String + Description: The access level for the KMS key used to sign and verify pipelines + AllowedValues: + - "sign-and-verify" + - "verify" + Default: "sign-and-verify" + Rules: HasToken: Assertions: @@ -727,6 +742,9 @@ Conditions: HasPipelineSigningKMSKey: !Or [ !Condition CreatePipelineSigningKMSKey, !Condition UsePipelineSigningKMSKey ] + HasSigningKMSAccessSignAndVerify: + !Equals [ !Ref PipelineSigningKMSAccess, "sign-and-verify" ] + HasKeyName: !Not [ !Equals [ !Ref KeyName, "" ] ] @@ -964,13 +982,17 @@ Resources: Statement: - Effect: Allow Action: - - kms:GetPublicKey - - kms:Sign - - kms:Verify + !If + - HasSigningKMSAccessSignAndVerify + - - kms:Sign + - kms:Verify + - kms:GetPublicKey + - - kms:Verify + - kms:GetPublicKey Resource: !If - - HasPipelineSigningKMSKey - - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKeyId} + - CreatePipelineSigningKMSKey - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKey} + - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/${PipelineSigningKMSKeyId} - !Ref 'AWS::NoValue' - !If - UseCustomerManagedKeyForParameterStore From 466633d7f15e97629049b930dde09e2317c70234 Mon Sep 17 00:00:00 2001 From: Mark Wolfe Date: Wed, 11 Sep 2024 13:54:04 +1000 Subject: [PATCH 7/7] Adjusted label to simplify heading --- templates/aws-stack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/aws-stack.yml b/templates/aws-stack.yml index 6b02ed5de..6e867cb4a 100644 --- a/templates/aws-stack.yml +++ b/templates/aws-stack.yml @@ -42,7 +42,7 @@ Metadata: - PipelineSigningKMSAccess - Label: - default: Advanced Buildkite Configuration + default: Advanced Configuration Parameters: - BuildkiteAgentRelease - BuildkiteAgentTags