- Get Started

Scopes, Rotation & Security

This page covers least-privilege scopes, credential rotation, and security best practices. For OAuth App creation, Coder integration, and test PAT setup, see the other Token Guide pages.

Token scopes and least privilege

Least privilege is not a one-time decision; it is a continuous constraint. Review the scope set every time you add a new skill, model, or integration that might require additional GitHub access. Ask the same question for every new permission: can the agent accomplish the task with a narrower scope?

Minimum viable scopes

For a standard repository that contains application code and documentation, the minimum production scope set is repo plus read:org and user:email. Add workflow only if the agents must modify GitHub Actions. Avoid admin:repo_hook, delete_repo, and any org-admin scopes unless a specific, reviewed operation requires them.

Audit the OAuth App regularly

GitHub records every OAuth authorization in the organization audit log. Review the log monthly for unexpected users, unexpected scopes, or authorizations from unknown IP addresses. Revoke any authorization that does not match a known tenant or user.

Restrict the Coder API token

The orchestrator does not need to create users, modify organizations, or change deployment settings. Create a custom Coder role with only the permissions listed in the Coder Integration guide and assign that role to the orchestrator user. If Coder supports token-level scope restrictions, apply them.

Rotation

All long-lived credentials should be rotated on a schedule and immediately after any suspected exposure. Rotation is a safety mechanism, not an emergency-only procedure. The schedule below is a starting point; adjust it to your own security policy.

CredentialRotation triggerProcedure
OAuth App client secretOn exposure, or annually as policy dictatesGenerate a new secret in the GitHub OAuth App settings, update GITHUB_OAUTH_CLIENT_SECRET, restart the OpenFlows orchestrator, and revoke the old secret.
CODER_SESSION_TOKENEvery 90 days, or immediately after personnel changesCreate a new token in the Coder dashboard, update CODER_SESSION_TOKEN, restart the orchestrator, then revoke the old token.
Test GitHub PATPer CI run or every 30 days in long-lived test bedsDelete /tmp/github_token, create a new PAT, write it to /tmp/github_token with mode 600, and re-run the test suite.

Rotation checklist

  1. Generate the replacement credential in the upstream system (GitHub OAuth App or Coder dashboard).
  2. Update the secret in your secret manager or orchestrator environment.
  3. Restart the OpenFlows orchestrator to pick up the new value.
  4. Verify that the next tenant command or poll cycle succeeds.
  5. Revoke the old credential only after the new one is confirmed working.

Rotate before you have to

Set a calendar reminder for credential rotation 30 days before expiry. Rotating under pressure increases the risk of mistakes, such as leaving the old secret in a backup or environment variable. A documented rotation runbook is part of a secure deployment.

Security best practices

Tokens are the keys to the kingdom. Protect them with the same rigor you would apply to a production database credential.

Troubleshooting

Most authentication failures fall into a small number of patterns. The table below maps common errors to their causes and fixes.

SymptomCauseFix
401 Bad credentials when OpenFlows calls GitHubOAuth App token expired, PAT revoked, or /tmp/github_token missing.Verify the Coder external auth session is current, re-authenticate the tenant in the Coder dashboard, or confirm the test PAT file exists and is readable.
403 Resource not accessible by integrationOAuth App scopes are insufficient or the app is not installed on the target repository/organization.Check the OAuth App scopes, confirm the app is authorized for the organization, and re-run the tenant authorization flow.
401 Unauthorized from Coder APIThe CODER_SESSION_TOKEN is missing, expired, or lacks the required scopes.Verify the token in the Coder dashboard, ensure it has workspace and template permissions, and restart the orchestrator.
OAuth callback mismatchThe GITHUB_OAUTH_REDIRECT_URL does not match the authorization callback URL in the GitHub OAuth App.Compare the two values exactly, including the scheme and trailing slash, and update both sides to match.
Tenant authorization prompts repeatedlyThe Coder external auth session has a short lifetime and is not being refreshed automatically.Check the Coder external auth provider configuration, confirm the refresh token is being stored, and review the Coder server logs.

If the issue persists after checking the items above, inspect the Coder server logs and the OpenFlows orchestrator logs together. The most useful signals are the exact HTTP status code from the Coder API, the GitHub API response headers, and whether the failure happens during tenant provisioning or during a GitHub operation.

Still stuck?

Check the FAQ for repository-specific issues, the Environment Variables reference for the full variable list, and the Troubleshooting Guide for deeper diagnostic steps.