> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Governance

> How GitHub Environments secure deployments using branch restrictions, required reviewers, environment-scoped secrets, and OIDC issued short-lived cloud credentials.

Secret management often looks simple: add a secret and reference it in your workflow YAML. This article explains how [GitHub Environments](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment) add important guardrails for safe deployments.

Think of an environment as a native deployment target. Within an environment you can configure three complementary layers of protection that work together: branch mapping, manual approvals (required reviewers), and environment-scoped secrets. Together these controls ensure only the right code, approved by the right people, receives access to sensitive values.

Example: referencing a secret in a workflow job that targets an environment:

```yaml theme={null}
# .github/workflows/deploy.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: Deploy
        env:
          API_KEY: ${{ secrets.API_KEY }}
```

1. Branch mapping — restrict which branches are allowed to deploy to this environment\
   First, map which branches may deploy to a given environment. For example, configure your `production` environment to accept deployments only from `main`, or from branches that match a pattern. If someone attempts to trigger a production deployment from an unmapped feature branch, GitHub blocks the job immediately before it starts. This prevents accidental exposure of environment-scoped secrets or unintended deployments from experimental branches.

2. Manual approvals — the human gate\
   Second, require manual approval by specifying required reviewers for the environment. When a workflow targets an environment that requires review, GitHub pauses the run and notifies the designated reviewers. The deployment will not proceed until one of the reviewers clicks Approve. This built-in change-control step produces an audit-ready trail of who approved the deployment and when.

Require reviewers to enforce a human checkpoint. This is useful for enforcing release policies, performing safety checks, or ensuring compliance before sensitive secrets are used.

Console message you may see when approval is required:

```text theme={null}
deploy (production)
Waiting for review
Review required before this job can start
```

3. Environment secrets — scoped and locked behind the other gates\
   Third, store sensitive values (for example, production database passwords) as [environment secrets](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#environment-secrets) on the environment itself. Because these secrets are scoped to the environment, they are inaccessible unless both the branch mapping and manual approval gates are satisfied. A developer cannot read or expose those secrets from an unmapped feature branch because the branch mapping prevents the job from starting and the manual approval step is never triggered.

![The image is a diagram titled "Environment Secrets" showing a UI panel listing two secrets (PROD\_DB\_PASSWORD and PROD\_API\_KEY) and a deployment flow: a developer → branch mapping → manual approval → environment secrets, with a note that secrets are never handed out.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/GitHub-Actions-and-Runners/Environment-Governance/environment-secrets-developer-branch-approval.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=1213382430362bf3dc5d3e7cfecbb7b4)

OIDC: remove static credentials by using short-lived tokens\
For cloud deployments you can avoid storing long-lived cloud credentials in GitHub by using [OpenID Connect (OIDC)](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect). Instead of keeping a permanent AWS key in GitHub, the workflow requests an OIDC token from GitHub. GitHub issues a signed [JSON Web Token (JWT)](https://jwt.io/introduction) that contains precise claims such as repository, ref, workflow, and environment.

Example OIDC token claims:

```json theme={null}
{
  "repository": "acme/payments-api",
  "ref": "refs/heads/main",
  "workflow": "deploy",
  "environment": "production"
}
```

Your cloud provider (for example [AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)) verifies the token signature using GitHub's public OIDC endpoint and the provider's configured trust. If the claims match the provider's trust policy, the provider returns short-lived credentials (temporary access key ID, secret access key, and session token) that typically expire within an hour. This eliminates the need to store static, long-lived credentials in GitHub.

Do not store long-lived cloud credentials in your repository. Use OIDC where possible so your cloud provider issues short-lived credentials tied to the workflow context.

![A diagram illustrating the OpenID Connect (OIDC) flow between GitHub and AWS: workflow requests access, GitHub issues a signed JSON web token, AWS verifies it, and returns short-lived temporary credentials. It also shows claim checks (repository, ref, environment) and example credential fields (access key ID, secret access key, session token).](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/GitHub-Actions-and-Runners/Environment-Governance/github-oidc-aws-temp-credentials.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=3cbf3e07b4e71952696c465dc7474b9d)

Core facts for exams and practical use

| Core fact | Why it matters |
| - | - |
| Environments map deployments to specific branches. | Unmapped branches cannot start the job, preventing unintended runs and secret exposure. |
| Environment secrets sit behind both gates (branch restrictions and manual approvals). | Secrets are only available after the job is allowed to run and, if configured, a human approves the deployment. |
| Use OIDC and the JWT flow instead of static credentials. | The cloud provider validates the signed token and issues short-lived credentials, removing the need for permanent keys in GitHub. |

![A slide titled "Exam Facts" showing two numbered cards: 1) "Environments map deployments to specific branches" (with note that unmapped branches never start the job) and 2) "Environment secrets sit behind both gates" (noting branch restrictions and manual approvals). The page includes small icons and a copyright notice for KodeKloud.](https://mintcdn.com/kodekloud-c4ac6d9a/Ae2SeWV4btujbkSt/images/GitHub-Administration-Certification/GitHub-Actions-and-Runners/Environment-Governance/exam-facts-environments-branches-secrets.jpg?fit=max\&auto=format\&n=Ae2SeWV4btujbkSt\&q=85\&s=0262e47db39d83736f17240f08317e7e)

Summary: the JWT/OIDC flow looks like this — the action requests a token, GitHub issues the signed JWT containing repository/ref/workflow/environment claims, and your cloud provider verifies the token against GitHub's public endpoint. When the claims match the provider's trust policy, the provider returns short-lived credentials that remove the requirement for static, long-lived secrets in your repository.

Links and references

* [GitHub Environments documentation](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment)
* [Security hardening with OIDC (GitHub)](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
* [AWS OIDC provider setup](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html)

> [card] [Watch Video](https://learn.kodekloud.com/user/courses/github-administration-certification/module/3ba840c5-7afb-4da9-8395-a430a6354557/lesson/e1df854f-7a3d-464a-821d-6b92b5537e03)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.