Pages

Thursday, February 6, 2020

Storing secrets Using Aws Secrets Manager

Secrets are very commonly used in applications. A secret can be a password to connect to a database, an application ID or a token. Many of the times application teams write code using credentials to connect to the database. These credentials can be either plain or obtained from another file. Since security is becoming very important, what if we have a way to store these credentials in a location and access them while running our application in a secure way. I save the credentials like user name and password , associate a token to this credential and use that token in the application for connecting to the database. The location is called Valut in some cases. Aws provides us with a similar facility called Secrets manager.

In this article we will see how we can create secrets and access them from our application code,


Go to the Aws Services and search for Secrets Manager. On the Home screen, we can see a Create Secret button. Click on it and we will go to this page where we can create secrets. 

We can see that we have multiple options for creating secrets. We havev
Credentials for RDS database
Credentials for Redshift
Credentials for DocumentDB
Credentials for Other Databases
Other type of secrets

For this demo, i have chosen the “other type of secrets” and created a secret as below,
I am selecting the Default Encryption Key for this purpose. In the next screen,
We have to provide the name of the secret that we will use for retrieving in the code. I gave it the name “sample-key”. Now using this secret name,I will try to retrieve the secrets created.

In the next screen we can see the auto key rotation policy. Save the Secret. We can then run the sample boto python code as below,
jagadishm@[/Volumes/Work/aws/code]: cat access-secret-from-secretmanager.py 
import boto3
import base64
from botocore.exceptions import ClientError


def get_secret():

    secret_name = "sample-key"
    region_name = "eu-west-1"

    # Create a Secrets Manager client
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name='eu-west-1'
    )

    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
    except ClientError as e:
        if e.response['Error']['Code'] == 'DecryptionFailureException':
            # Secrets Manager can't decrypt the protected secret text using the provided KMS key.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'InternalServiceErrorException':
            # An error occurred on the server side.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'InvalidParameterException':
            # You provided an invalid value for a parameter.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'InvalidRequestException':
            # You provided a parameter value that is not valid for the current state of the resource.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
        elif e.response['Error']['Code'] == 'ResourceNotFoundException':
            # We can't find the resource that you asked for.
            # Deal with the exception here, and/or rethrow at your discretion.
            raise e
    else:
        if 'SecretString' in get_secret_value_response:
            secret = get_secret_value_response['SecretString']
            print(secret)
        else:
            decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
            print(decoded_binary_secret)
  
if __name__ == "__main__":
    get_secret()

Once we run the code, we can see the output as below,
jagadishm@[/Volumes/Work/aws/code]: python access-secret-from-secretmanager.py 
{"secret-key-1":"jagadish"}

How can our code running in Ec2 instance can access the secrets?
Now the very important thing is how can code running in the ec2 instances access the secrets from the secrets manager. This is where roles come into picture. 
1. Go to Services -> IAM -> Roles → Create Role.
2. Select the type of trusted entity as an AWS service
3. Select EC2
4. Hit Next- Permissions.
5. Search for the permission policy "SecretsManagerReadWrite" and select.
6. Hit Next-Tags.
7. Add tags if you need hit Next.
8. Give a role name and hit Create Role.
Once the role is created, go to the instance -> Actions and add role to that. Once you add the role and run the code, we can see the secrets created.

No comments :

Post a Comment