Secrets Management

Standards, values, and other information relevant to the NYPL Engineering Team.


Secrets Management

If secrets (e.g. API keys, database logins, or other credentials) are to be stored or shared, they MUST be stored or shared in one secure place, to signify one source of truth and to make resources easier to find.

AWS Parameter Store SHOULD be used to store secrets.

Parameter Store

Name conventions

Parameter names MUST use a hierarchy and list the environment name and other descriptors.

The name MUST include the following:

  • The first segment of the parameter name MUST be environment/stage/tier if applicable.
  • The service that this is a parameter for.
  • The app that uses this secret. This could be omitted if it’s a resource shared by multiple apps.
  • A description of what this is.

Examples may be:

  • /production/mms/rds/password-for-mms_productions-root-user
  • /production/elasticcache/my-cluser-name/password
  • /loggly/my-loggly-user-name/api-key (environment/stage/tier isn’t applicable)

Value conventions

Values MUST be stored as the SecureString type.

Values SHOULD be encrypted using the KMS Key ID alias/secrets-key.

A description SHOULD be provided (e.g. using the --description flag).

Values MUST be in JSON. For example:

{"username":"admin","password":"password123"}

Limits

Developers SHOULD be aware of the following limits with Parameter Store:

  • Name hierarchy has a maximum of 5 levels.
  • Maximum length of name is 2,048 characters.
  • Maximum length of value is 4,096 characters.

See the API Reference for current limits.

Sample AWS command line commands

Adding a parameter:

aws ssm put-parameter --name '/development/testservice/credentials/admin' --type 'SecureString' --key-id alias/secrets-key --description 'This describes this key' --value '{"username":"admin","password":"password123"}' --profile nypl-digital-dev

Getting a parameter:

aws ssm get-parameter --name '/development/testservice/credentials/admin' --with-decryption --profile nypl-digital-dev

Encrypting/Decrypting

Using the AWS Command Line

To encrypt a secret using the AWS command line:

aws kms encrypt --key-id alias/lambda-default --profile nypl-digital-dev --query CiphertextBlob --output text --plaintext "THIS IS A SECRET"

returns:

AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAGkwZwYJKoZIhvcNAQcGoFowWAIBADBTBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHM+CBbD63yvLYX7YAIBEIAmPAZ1EOrQMd5GRao2MTOyY16JZmMhOgDNJWvy1V3eWr1xHIWIuRo=

To decrypt a secret using the AWS command line:

aws kms decrypt --profile nypl-digital-dev --query Plaintext --output text --ciphertext-blob fileb://<(echo "AQECAHh7ea2tyZ6phZgT4B9BDKwguhlFtRC6hgt+7HbmeFsrsgAAAGkwZwYJKoZIhvcNAQcGoFowWAIBADBTBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDK5NDY0/rIiVt3rp4AIBEIAm5tjVxfouymAm2+UDCc6aYesUxlAXvU5lgI9VlQBYIrl7LozlQ2o=" | base64 --decode) | base64 --decode

returns:

THIS IS A SECRET