JupiterOne recently added support for ingesting GitHub Org, Repo, and Environment secrets.
Don't panic! We're only ingesting the metadata--just the data about the secrets, like their name and when they were created--not the secret values themselves! Fun fact, obtaining unencrypted secret values is not even permitted by the GitHub API.
GitHub Secrets metadata enables powerful use-cases such as secrets management, security review, and misconfiguration alerting. It allows you to securely store API tokens, passwords, and other secrets for use inside GitHub Actions builds/workflows.
GitHub Encrypted Secrets
First off, a quick review of how GitHub implements secrets:
- Encrypted secrets can be added at the top-level Organization, where they may be made available to All, Only Private, or Only Selected repositories. We recommend you practice least privilege and limit access to only selected, authorized repositories with a business need to access the Org secret.
- Encrypted secrets can be added to each Repository.
- Encrypted secrets can be added to a Repository Environment.
GitHub Environments are like targeted namespaces for sets of branch configuration, protection rules, and secrets for a given code repository. You might have less restrictive protection rules around the development environment, but tight restrictions with branch limitations for the production environment. Each environment would likely have a different set of credentials for a given Secret.
Security Review of Secrets Blast Radius
Security teams can periodically review which repositories have access to Secrets with a query, such as :
Find CodeRepo that USES Secret return CodeRepo.displayName, Secret.displayName ORDER BY Secret.displayName ASC
Auditing Secrets Rotation
Secrets should rotate regularly, especially when an employee with privileged access to those secrets is off-boarded. The following query can be added to a day-of offboarding checklist to facilitate the immediate rotation of impacted Secrets:
Find Secret with updatedOn < date.now
For compliance evidence purposes, you can easily demonstrate that all your secrets are rotated within a specified period (annually, 180d, etc):
Find Secret with updatedOn < date.now - 1 year
Find Secret with updatedOn < date.now - 180 days
Alerting on Secrets Overrides
When secrets are rotated, ideally there should be one and only one place where that secret value has to change.
Repo and environment secrets bind tighter than org-level secrets, meaning they may override the org-level values for a given Secret, by storing a secret of the same name. This override may be intentional, but in general, you want to avoid this approach, as it fosters a proliferation of secrets, makes it harder to reason about access, and makes updating/rotating secrets harder and more error-prone.
If a CodeRepo USES a github_repo_secret or github_env_secret, and a github_org_secret of the same name exists, JupiterOne will create an OVERRIDES relationship.
Let's analyze the Secrets graph to see if we can detect inappropriate overrides of a given Secret.
Find CodeRepo that USES github_repo_secret that OVERRIDES github_org_secret RETURN TREE
Here, we want to know if a Repo-level secret overrides an already defined org-level secret.
A more abstract and powerful version of the above query would also return cases where github_env_secrets override either org or repo-level secrets.
Find CodeRepo that USES Secret that OVERRIDES >> Secret RETURN TREE
Note that here we use the relationship direction operator, >>, to specify a direction to enforce during graph traversal. By default, JupiterOne relationships are bidirectional, and this default would select too much with an abstract query like this one.
We'll add a query similar to the above to an alert rule, like so:
Active (undismissed) JupiterOne alerts now generate Problem entities in the graph. Expanding the middle github_repo_secret, we see this relationship, too:
Therefore, another way of asking for currently problematic Secrets, assuming we're alerting on any of the above queries, is:
Find Secret that HAS Problem
At-a-Glance View of Secrets Footprint
You can get a sense for your total Secrets footprint in GitHub with a query like the following:
Find (github_account|github_repo|github_environment) that HAS Secret RETURN TREE
This query utilizes the HAS relationship, which indicates parentage (where the secret comes from), as opposed to the previous queries, which relied on the USES relationship (what is permitted to access the secret). This produces a graph like:
Conclusion
Secrets management can be tricky. Adopting secrets management is an important step in improving your organization's security posture. JupiterOne helps you bring additional visibility to this problem space, and now offers a path to insight about the state of your secrets in GitHub.