AWS Secrets Manager
Secrets Manager is a managed service which enables relatively easy rotation, retrieval and management of secrets like API keys, database credentials, and other sensitive information. Nicely integrates with RDS, Redshift, DocumentDB. Enables fine-grained access control and audit secret rotation in centralized way. Another great aspect of this service is pricing model - pay as you go (pay for number of secrest in Secrets Manager and number of API calls made).
Storing
Using following cloudformation template, secret will have generated attribute named secret
and provided attribute with name
and value foo
. Secret generation can be nicely configured to include/exclude certain characters, have specific length and letter uppercase/lowercase presence.
SecretOne:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Sub ${Env}-${App}-secret-one
Description: 'Generated secret'
GenerateSecretString:
SecretStringTemplate: '{"name": "foo"}'
GenerateStringKey: 'secret'
PasswordLength: 30
ExcludeCharacters: '"@/\'
Tags:
- Key: App
Value: !Ref App
- Key: Env
Value: !Ref Env
This template provides secret without generation, so it will contain static information. Both name
and secret
attrubute values will remain as provided and nothing will be added/changed.
SecretTwo:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Sub ${Env}-${App}-secret-two
Description: 'Secret without generation'
SecretString: '{"name": "foo", "secret": "(づ。◕‿‿◕。)づ"}'
Tags:
- Key: App
Value: !Ref App
- Key: Env
Value: !Ref Env
SecretThree:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Sub ${Env}-${App}-secret-two
Description: 'Secret without generation'
SecretString: '{"name": "baz", "secret": "(ノ◕ヮ◕)ノ*:・゚✧"}'
Tags:
- Key: App
Value: !Ref App
- Key: Env
Value: !Ref Env
Retrieving
Can be done in multiple ways. Here is a programmatic one, secrets are referenced and their ARN
s are baked into lambda environment variables with corresponding names SECRET_ONE
& SECRET_TWO
, another important thing is that lambda must have permissions to access those secrets (allow secretsmanager:GetSecretValue
action). The last step is to fetch secrets via AWS SDK which is trivial.
Feature:
Type: AWS::Serverless::Function
Properties:
Description: Feature using secrets
FunctionName: !Sub ${Env}-${App}-feature
CodeUri: app/feature/
Handler: handler
Runtime: go1.x
Environment:
Variables:
SECRET_ONE: !Ref SecretOne
SECRET_TWO: !Ref SecretTwo
SECRET_THREE: '{{resolve:secretsmanager:SecretThree}}'
SECRET_THREE_NAME: '{{resolve:secretsmanager:SecretThree:SecretString:name}}'
SECRET_THREE_VALUE: '{{resolve:secretsmanager:SecretThree:SecretString:secret}}'
Policies:
- Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- !Ref SecretOne
- !Ref SecretTwo
- !Ref SecretThree
Tags:
App: !Ref App
Env: !Ref Env
Another handy option to retrieve secret is by referencing it in Cloudformation
template in special way.
{{resolve:secretsmanager:secret-id:secret-string:json-key:version-stage:version-id}}
While referencing it’s possible to define which attribute we waht to fetch.
SECRET_THREE: '{{resolve:secretsmanager:SecretThree}}'
SECRET_THREE_NAME: '{{resolve:secretsmanager:SecretThree:SecretString:name}}'
SECRET_THREE_VALUE: '{{resolve:secretsmanager:SecretThree:SecretString:secret}}'
Rotation
Secret manager delegater secret rotation logic to lambda function. Rotation happend according to schedule previously set. Lambda is called several times during rotation, every time with different set of parameters.
Stages
- create a new version of the secret (createSecret)
- change the credentials in the database or service (setSecret)
- test the new secret version (testSecret)
- finish the rotation (finishSecret)
Conclusion
Secret manager comes with additional cost per secret. Provides automatic secret rotation. Able to generate random secrets. Another important feature is ability to share secrets across accounts.