AWS Systems Manager to store encrypted keys
Please, please, never, ever store your passwords, access keys, or any IDs in your code. This happens way too often, and since most of our code is on Public repositories - Amazon actually had to build a service that scans the repos for confidential info, like AWS credentials.
If you’ve just landed here, we’re doing a “Become a Cloud Architect” Unicorn Workshop by building a Unicorn Pursuit Web App step by step, and you’re more then welcome to join!
We have two options: Systems Manager (SSM) and Secrets Manager, and if you’re trying to reduce cost - SSM is free!
About Systems Manager Parameter Store
Systems Manager Parameter Store can be used to store confidential information. You can store it in plain text, or encrypt using KMS. The idea is to use your code and go to Parameter Store to retrieve the value of the Key.
For example, within the EC2 “Instance Type” parameter, we would use SSM to define that devInstance equals whichever instance type we want, and then in the YAML parameter section. This wouldn’t need an encryption:
InstanceType:
Type: 'AWS::SSM::Parameter::Value<String>'
Default: devInstances
However, if we are using something like Cognito Application Client ID, this is confidential… it would be like publishing your Passport number with expiration date to the whole world, so we want to encrypt that info.
We need to configure this in the AWS Console. First, find the Systems Manager service from the AWS Console, and go to Parameter Store:
Before you create your parameter, make sure you have Keys in your KMS. In Unicorn Pursuit, we’ll use AWS managed keys:
Watch it here, as you pay US $1/month to store any key that you create. AWS managed keys that are created on your behalf by AWS services are free to store. So let AWS create this key for you, don’t create keys.
Now go back to Systems Managet to create your Parameter, and give it a Name you’ll reference from your code, and a Value (secret stuff you don’t want others seing), as shown below:
What about Secrets Manager?
We don’t want to be hard-coding Passwords, we want to create reusable code, as much as possible, so for actual production - Secrets Manager might be a better option. Have in mind that the price is 40 cents a month per secret. Not a lot, but… there’s a cost, not like SSM where parameters are for free.
The big advantage of Secrets Managers is that from Secrets Manager we can automatically rotate our keys, and generate random passwords, AND you can share secrets across multiple accounts.
Code
Before we get into Code, let’s understand what we’re building. Check out the diagram below:
Since in Unicorn Pursuit all the calls to the functions are done from routes.go
, that where we’ll establish the SSM session and retrieve our Cognito App Client ID, and store it in the variable ClientIDValue
. We need to import the module:
"github.com/aws/aws-sdk-go/service/ssm"
and then, get the value and store it in the new string variable:
// Get value of Cognito Application Client ID
ssmsvc := ssm.New(sess, aws.NewConfig().WithRegion("eu-west-1"))
ClientIDKey := "CognitoAppClientID"
withDecryption := true
param, err := ssmsvc.GetParameter(&ssm.GetParameterInput{
Name: &ClientIDKey,
WithDecryption: &withDecryption,
})
// ClientIDValue stores the value of Cognito Application Client ID
ClientIDValue := *param.Parameter.Value
Before getting to the actual configuration, be sure to check if the SSM is returning the correct value. A neat trick is to print it, so you can compare if everything is Ok.
ClientIDValue := *param.Parameter.Value
fmt.Println(ClientIDValue)
That’s it, we can now reference ClientIDValue
in our code instead of exposing confidential information.
Feedback
Was this page helpful?
Awesome! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.