I've created a GitHub action that works that allows GitHub Actions to exchange a GitHub token for AWS Access Credentials.
I've cultivated a few examples of it in action:
https://github.com/saml-to/aws-assume-role-action-examples
I've always found management of AWS Credentials has been a pain. So this setting up this Action works like this:
1) A SAML Identity Provider is created in AWS
2) A Role in AWS is set up to trust that Identity Provider
3) A config file is added to the repository indicating which role can be assumed
4) The GitHub Action exchanges the Repo Secret for AWS Credentials using the SAML.to backend for the exchange
Let me know what you think! I'm Happy to take questions and comments here or on Gitter:
A title like "Show HN: A GitHub action to help using AWS credentials" sounds more appropriate to me, saying what it is and what it does instead of saying what not to do.
I'll heed your advice for the next time I post something on HN, thank you!
Writing titles that are direct enough for HN but still enthusiastic and marketable can be hard. I can't find the comment right now, but someone said a good rule is to start with "what it is" then "what it does" and last "why you think it's good"
Why does SAML.to need to be used?
You are correct this GitHub action is at its core is very similar! Even though the initial instructions don't prescribe it, the biggest differentiator is that SAML.to supports a centralized permissions configuration across all repositories for a user, project or organization:
https://github.com/saml-to/assume-aws-role-action/blob/main/...
Also, this action is the tip of the iceberg of what SAML.to aims to provide (check out https://saml.to), for example:
- Store Role Assumption and Privileges as Code (the saml-to.yml config file) - A command line interface to login and assume roles - Free (or affordable) for small teams or individuals - Additional Automations, Webhooks, SCIM, etc
Let me know if you have any comments on this and thanks for the question!
* it seems your package.json is still from an old iteration: https://github.com/saml-to/assume-aws-role-action/blob/main/...
* it was super opaque where this relative import comes from: https://github.com/saml-to/assume-aws-role-action/blob/main/... but after some sniffing around, it seems to be some openapi generation magick https://github.com/saml-to/assume-aws-role-action/blob/main/... against one of your own API endpoints https://github.com/saml-to/assume-aws-role-action/blob/main/... which seems to mean that using this toy is not "self contained" in the way that `sts:AssumeRoleWithWebIdentity` is
I updated package.json!
On the note of the API endpoint. Yes that's correct, I've fashioned a backend API which handles converting of GitHub Repo Tokens to SAML Assertions: https://sso.saml.to/github/swagger.html#/IDP/AssumeRoleForRe...
And providing a static endpoint for SAML Metadata: https://saml.to/metadata
That being said, you're making my brain click a little bit and this could be converted into a "self contained" toy, with some additional work! The biggest piece of the puzzle is a consistent private key and certificate.
If that is of interest to you, could you create a GitHub Issue as a feature request?
Thanks!
Other than never exposing keys like that I learned to never hide admin keys and to always create roles specific to the use case. It doesn’t fully protect you but at least it prevents abuse on your behalf.
I've found a lot of SaaS providers only support SAML today, so you're stuck if you want to use GitHub identity outside of OIDC.
(which appears to be rather similar to saml-to, just with OIDC instead of saml.) The reason being that we try to avoid creating long-lived credentials at all where I work. Everyone uses SSO to sign into AWS with a provisioned IAM role, no one has an IAM user, etc. This means there just _aren't_ credentials floating out there, SSO sessions last 12 hours, and Github gets an OIDC token when it needs one.
This means there are no credentials to leak (for the most part- there are some edge cases that necessitate creating an access key), they generally are harder to mix up (each aws account is for a separate business purpose, so there are lots of them), and CloudTrail lists _who_ did every action since SSO adds your email to your IAM identity and devs don't have long-lived service credentials.
In short, there's nothing _wrong_ with using Secrets to store your tokens, but it's useful in some cases for cohesion. If you're already handing out long-lived tokens to devs or other services, there's not really any reason to stop doing that with github.
A static credential is sometimes shared among many users, making it very difficult to audit their use.
When was the last time you changed the AWS credentials when somebody left a company? They probably still have the old credentials and they probably still work.
If your computer gets infected with malware, the malware can look for credentials on your system (not difficult to match on them with regular expressions searching through files).
Some people use their own user's personal static credentials for things like CI/CD, and their personal static credentials often have Admin access to the AWS account. This is a lot more access than should be given to some automation system.
A hacker can use them to spin up 100 giant EC2 instances in your AWS account to mine crypto / send spam / DDoS, and charge your AWS account $500,000 in a month.
Personally I trust GitHub to get the security right more often than I will.
I'll echo what I just responded to nodesocket with, but I'd also love your feedback on my comment:
But you say you find "management of AWS Credentials a pain", so I guess this isn't for security purposes, right? More of just a convenience?
Don't get me wrong, I'm all about lessening the amount of environment variables in a pipeline!.. especially with ones that you want to rotate!
Ref: https://docs.github.com/en/actions/security-guides/automatic...
And the SAML.to backend first checks to make sure the token is valid by invoking:
Ref: https://docs.github.com/en/rest/reference/apps#list-reposito...
I haven't checked, but I assume GitHub invalidates the token when the GitHub Action finishes
Storing Secrets in GitHub isn't technically insecure, and it's awesome it's provided as a free feature, but it's tedious and fragile. Someone (or something has to do various clicks and copy/pastes or API calls) to upload an access key into GitHub Secrets. It gets even worse if you have multiple accounts and then your Action Workflow file gets really gnarly if you simply pull credentials from ${{ secrets.* }}.
Also, if you need to rotate your AWS access tokens, you open up a whole new can of worms, so why not remove credentials all together!
Thanks for the question nodesocket, let me know if you have more questions or comments!
However you now have long-lived keys.
They tend to get used across multiple projects, and despite the best practice being to rotate keys frequently, it's rarely done.
You also have no idea who has them, and without the use of, say, Cloudtrail, you don't know if anyone is using them (even Cloudtrail might not pick up on everything)
The approach here is to get short-lived keys, when they are needed.
Do you rotate your keys in secrets regularly?
is that a question/comment for me?