Skip to content

API Keys in Secrets

How to store and rotate API keys securely in your CI system.

The API key authenticates your CI against the CodeCharter portal. It is just as sensitive as a production database password and should be treated accordingly.

Where keys belong

CI system Storage location
GitHub Actions Repository Secrets or Org Secrets
GitLab CI Project Variables (Protected, Masked)
Azure DevOps Library Variable Groups, secret-locked
Bitbucket Pipelines Repository Variables, Secured
TeamCity Project Parameter, type "Password"
Jenkins Credentials Manager, "Secret text"

Where keys do NOT belong

  • Never commit them to the repo. Not even "just for a quick test". Git history is permanent — a key that was once exposed is burned.
  • Not in logs. If a script contains echo "Key: $CODECHARTER_API_KEY", it will appear in the build log and potentially in artifacts and security scans.
  • Not in .env files that you might accidentally share in backups, Slack threads, or wikis.

Masking in CI logs

Most CI systems automatically mask secret variables in logs when they are marked as secrets. Still, watch out for:

# Bad — the token ends up as a URL parameter in the log
curl "https://example.com/?token=$CODECHARTER_API_KEY"

# Better — as a header, which is not logged
curl -H "Authorization: Bearer $CODECHARTER_API_KEY" https://example.com/

Rotating a key

If a key is compromised or a team member leaves who may have seen it in plain text, replace it like this:

  1. Generate a new key in the portal under API Keys.
  2. Store the new key in the CI system (update the secret variable).
  3. Run the CI once and confirm everything is green.
  4. Revoke the old key in the portal.

Multiple keys can be active at the same time, so you can take your time with steps 2 and 3 before revoking the old one in step 4.

One key per repo or per team?

A good rule of thumb:

  • One key per CI job family. If you have five repos all running CodeCharter, one key is enough. But if you have a public repo and an internal repo: use two keys.
  • Not one key per developer. Keys belong to CI, not to individuals.
  • Meaningful names. You can give a key a name in the portal. acme-web-ci is good, prod-key is okay, key is not helpful during an audit.

Key compromised — what to do

  1. Revoke the key immediately in the portal.
  2. Generate a new key.
  3. Update the CI secret variable.
  4. Check for unusual pull activity in the logs (portal audit).
  5. If the key was publicly exposed (e.g. in a PR): GitHub Secret Scanning typically fires automatically. We also receive a notification and can force-revoke the key on our end.

Lifecycle

In the portal you can set a lifetime per key (e.g. 90 days). After expiry the key is automatically deactivated. Useful for temporary keys, for example for an external consulting firm that needs temporary access to your CI.

See Managing API keys.