-
Notifications
You must be signed in to change notification settings - Fork 0
Step by Step Setup (SAM or CloudFormation)
The Platform Client Secret Rotator is an application distributed on the AWS Serverless Application Repository (SAR). If you're familiar with npm, NuGet, Cargo, or any package manager for a programming environment or operating system, then the SAR will be familiar to you. In it, developers can distribute sets of CloudFormation resources what work together to perform a task. The AWS Serverless Application Model (SAM) has first-class support for components distributed in this way. (Which shouldn't be much of a surprise, given the name.)
Let's turn a CloudFormation template into a SAM template.
Transform: AWS::Serverless-2016-10-31That's it. Putting that element at the top level – the minimum indentation level – of a CloudFormation template will instruct CloudFormation to perform the "Serverless" transform on the template. If a template has no Serverless resources, this will be a no-op. Let's add one. (By the way, the examples here will build up to the full example back in the project README.)
ExampleSecretRotator:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: arn:aws:serverlessrepo:us-east-1:820870426321:applications/platform-client-secret-rotator
SemanticVersion: 2.2.1
Parameters:
Endpoint: !Sub https://secretsmanager.${AWS::Region}.${AWS::URLSuffix}
FunctionName: !Sub ${AWS::StackName}-client-credentials-secret-rotator
KmsKeyArn: !GetAtt EncryptionKey.ArnBecause this is a CloudFormation resource, be sure this is under – in the indentation scope of – the Resources key.
The value for Type is a resouce of the type AWS::Serverless. It will be transformed into one or more other CloudFormation resources by the "Serverless" transform. In this case, an AWS::Serverless::Application becomes an AWS::CloudFormation::Stack, but there's not always a one-to-one correspondence. The keys and values under the Location property are required for all resources of type AWS::Serverless::Application. The ApplicationId is the identifier, and should not change. The SemanticVersion can change, and you should make sure that you are using the most up-to-date version.
The ApplicationId is specifically an opaque identifier. Even though there are a region ID and an account ID in there, they really do only identify the application. The resources which are produced run in your deployed account, in your deployed region, with your deployed permissions. If you would like to fork Cimpress-MCP/Platform-Client-Secret-Rotator, you are of course welcome to. But there's no reason to if you are only consuming it.
The keys and values under the Parameters property are specific to the Platform Client Secret Rotator. The value specified for Endpoint in this example is almost always the endpoint you want to use. However, if your account has external network access particularly restricted, and you have created a service link route to AWS Secrets Manager, supply the address of that route here instead. If that doesn't mean anything to you, use the provided value. The value specified for FunctionName must be unique in an account–region combination. The value for KmsKeyArn is only required if the secret is encrypted with a CMK. (This is recommended.)
The parameter OverlapDuration controls how long after rotation a previous client remains valid. This defaults to P1D, which is "one day" in ISO-8601 Duration syntax. "One hour" is spelled PT1H, and so on.
ExampleSecret:
Type: AWS::SecretsManager::Secret
Properties:
Description: An example client ID and secret.
GenerateSecretString:
SecretStringTemplate: |-
{ "id": "<<client_id>>" }
GenerateStringKey: secret
PasswordLength: 64
ExcludeCharacters: |-
!"#$%&'()*,/:;<>?@[\]^`{|}~
KmsKeyId: !Ref EncryptionKeyThis is the actual AWS Secrets Manager secret in which the client credentials will be stored. The GenerateSecretString property is what makes it so that secrets can be created containing secret values, but without putting that secret value into the template. In SecretStringTemplate, <<client_id>> should (of course) be replaced with the client ID of the client whose secret will be rotated. The other properties of GenerateSecretString should not be altered for customization purposes. The rotator will not work if the value of GenerateStringKey is anything other than "secret". The value of PasswordLength can be set to any value between 32 and 127, but 64 should be suitable for any reasonable purposes. The value of ExcludeCharacters is set to ensure that the generated secret is valid. This secret is encrypted with a KMS CMK.
ExampleSecretRotationSchedule:
Type: AWS::SecretsManager::RotationSchedule
Properties:
RotationLambdaARN: !GetAtt ExampleSecretRotator.Outputs.RotationLambdaARN
RotationRules:
AutomaticallyAfterDays: 30
SecretId: !Ref ExampleSecretThis resource connects the rotation Lambda Function to the secret. The rotation schedule of 30 days can be customized, but 30 should be suitable for any reasonable purposes. For security hygiene, it should not be set above 90. Once this resource is deployed, it will immediately attempt a rotation. This rotation will fail, but for a good reason.
There is an unavoidable bootstrapping step when deploying the Platform Client Secret Rotator into a service for the first time. The deployment process has no way of knowing what a client's current secret is (nor should it!), so the first rotation which occurs after deployment will necessarily fail. To take ownership of the rotation of a client secret, transfer the previous client secret value into the secret in AWS Secrets Manager and instruct AWS Secrets Manager to rotate the secret immediately. Once the secret in AWS Secrets Manager and the secret in Auth0 match, it's hands-off operation. A manual rotation can be initiated at any time via AWS Secrets Manager.