Secret Id in AWS Secret Manager - amazon-web-services

We deployed our complete application in AWS environment and We find AWS Secret Manager is the right choice to store the secrets for the database and a few other components.
Our ultimate aim is not to store any credentials in the config file / database. It is achieved using AWS Secret Manager.
But when I try to connect the AWS Secret Manager for retrieving the secret value, I see it expects a field like "secret-id" as shown below, I need to protect this secret-id in some location so that I can use this in the application for accessing the secret value.
aws secretsmanager get-secret-value --secret-id tutorials/MyFirstTutorialSecret

If you want to hide your secret-id, you better have another security layer. How about store those secret-id in somewhere, AWS DynamoDB?
| id | secret-id |
| abc123 |tutorials/MyFirstTutorialSecret|
Then create a customized script (Bash/Python) which can be only accessed by you and privileged users?
$MYSECRETID = <Retrieve it from DynamoDB using `id` key>
aws secretsmanager get-secret-value --secret-id $MYSECRETID

AWS doesn't permit what you want as it uses the name of the secret as part of the ARN. However, you can either try to do some indirection like #leondkr suggests, or use policies to restrict who can even list what secrets exist. That could be done in either IAM or in the secret resource policy. See here for more information: https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access.html The privilege you may want to restrict is secretsmanager:ListSecrets.
Here are the IAM actions for that service: https://docs.aws.amazon.com/service-authorization/latest/reference/list_awssecretsmanager.html

Related

Is it possible to share Parameter Store keys in another AWS Account for same region?

The use case: The database credentials are stored in Parameter Store for an AWS source Account and we need to share such credentials with other AWS Account.
I know the recommendation is to use System Manager, but that is not a valid option for custom reasons.
We won't access Parameter Store from a Lambda inside another AWS Account/VPC. Instead, we need to access such keys from the AWS CLI to fill in the application environment variables at build time - again, it's not ideal. 🤷‍♂️
In summary, we have an AWS Cross-Account / Same region / IAM user (another account) scenario to access the Parameter Store keys from the source AWS Account.
Thanks in advance for any kind of guidance/direction 👊
I think you could create an IAM Role in the account with parameter store, give that Role permission to access parameter store, and configure it to let the IAM user you created in the other account to assume that Role and do what it needs.
Something like aws sts assume-role --role-arn "arn:aws:iam::123456789012:role/example-role" --role-session-name AWSCLI-Session and then aws ssm get-parameter --name "MyStringParameter"
to make it short: its not possible to share parameter store, only secrets from secrets manager

AWS Crossaccount - Parameters Store / Secrets Manager access to parameters in AWS CDK

I'm wondering if something is possible at all, or I'm trying to build something that is not possible from the start.
Let's say within Account A there is an RDS DB Password, (can be any AWS resource ID or value) that I have stored in Secrets Manager or Parameter Store.
Now I want to use that value in AWS CDK in Account B, is this possible?
It is possible to retrieve the value based on ARN, see: https://bobbyhadz.com/blog/get-secrets-manager-values-aws-cdk#get-secrets-manager-value-by-arn---alternative but would this work cross-account?
You can attach a policy to your secret granting access to other AWS account. Check https://aws.amazon.com/premiumsupport/knowledge-center/secrets-manager-share-between-accounts/

AWS EC2 userdata encryption

We have usecase of taking input which includes password from user and pass it to on EC2 instance. From with in Ec2 instance we hit the URL - http://169.254.169.254/latest/user-data/ and get the userdata and set appropriate passwords.
The issue is user data is visible by AWS CLI tool:
aws ec2 describe-instance-attribute --instance-id --attribute userData --output text --query "UserData.Value" | base64 --decode
This imposes huge security risk.
Whats the best way to send sensitive / secret data ?
I tried creating a key-pair, which creates the private key on local instance and public key on EC2. What would be right way to encrypt / decrypt using PowerShell and fetch it back in EC2?
The suggested approach would be to store any secrets in an external source.
AWS has a service for storing secrets, Secrets Manager. By using this service you would create a secret containing the secrets that your instance will need to access in its user data. Then give your instance an IAM role with privileges to get the secret value, via the AWS CLI.
Alternatively you could also make use of the AWS SSM Parameter Store service, storing the secrets as a SecureString type. This would work similar to secrets manager with you retrieving the secret via the AWS CLI and then using it in your script.
There are also third party solutions such as Hashicorp Vault that provide similar functionality if you do not want to store your secrets in an AWS solution.

What is the best possible way to pass API key for AWS EC2 user data script

I have bash script to run as user data script when launching EC2 instance. For that I need to pass external API access key id and secret key. I don't want to store these keys in my user data scripts as it is visible in plaintext. Is there any way that I can store this keys in somewhere such as AWS Secret Manager and use that in user data scripts?
I would suggest either storing it in Secrets Manager or SSM Parameter Store.
You would need to use the CLI in your userdata script to retrieve the value.
For SSM you would retrieve the secret by using the get-parameter function.
secret=$(aws ssm get-parameter --name "MyStringParameter")
For Secrets Manager you would retrieve the secret using the get-secret-value function.
secret=$(aws secretsmanager get-secret-value --secret-id MyTestDatabaseSecret)
Then in your bash script when you want to reference it you would just need to use the variable $secret to actually replace with your secret.
If you decide to use either of these you will need to ensure EC2 instance has an IAM role attached to the instance with the correct policy to apply the permissions you require.
Alternatively if this is a process that happens frequently (autoscaled instance for example) then you should take a look at configuring the base server image (AMI) ahead of time and then referencing this as the source AMI.
With tools such as Ansible, Chef and Puppet you could provision the base image with your secret which would replace any need to do anything in the UserData as it would be available ahead of time.
Usually you can store such secrets in AWS Systems Manager Parameter Store which is free, unlike AWS Secret Manager:
AWS Systems Manager Parameter Store provides secure, hierarchical storage for configuration data management and secrets management. You can store data such as passwords, database strings, Amazon Machine Image (AMI) IDs, and license codes as parameter values.
To use that in your UserData, the instance role has to be set with permissions to access the Parameter Store. Then in your UserData you can use aws cli get-parameter to get the value of your secrets.

Can I get a user's s3 canonical ID from the command line?

I'm creating special-purpose users for Amazon S3 access, for example to give out to a third-party service. The accounts don't have an email address or password. I was hoping I'd be able to pull the canonical ID of these accounts using the aws command-line tool.
One way I have read about is to create a bucket using their account, look at the acl for it, and extract the canonical ID from that, then delete the useless bucket and move on.
But for future use, is there an easier way?
If you run:
aws iam list-users
You get a list of all of your IAM users. One of the fields is UserId, which is defined as "The stable and unique string identifying the user".
If that is what you are looking for, then you can retrieve it with:
aws iam get-user --user-name <iam user name> --query 'User.UserId'
If you're looking for the canonical ID of account then use s3api::list-buckets
aws s3api list-buckets --query "Owner.ID"
Assumes you have setup the credentials somehow.
Source.
You should try this:
aws sts get-caller-identity