Source control & the policy check
Concept
Greenlight enforces a single delivery path: pull request, policy check, merge, deploy. There are no out-of-band writes and no shortcuts. The same path applies to the coding agent, the citizen developer, and IT.

What the check runs
Section titled “What the check runs”Greenlight’s policy check is a single status that posts on every pull request and aggregates four kinds of analysis.
| Check | What it catches |
|---|---|
| Secret scanning | API keys, tokens, and private keys committed in the diff. |
| Static analysis | Known-bad patterns, OWASP rules, and any custom organization rules you’ve enabled. |
| Supply chain | Container CVEs, dependency vulnerabilities, and license-policy violations. |
| Org policy bundle | Organization-specific rules evaluated by OPA — approved base images, resource limits, dependency allow-lists, and anything else in your policy bundle. |
The policy bundle is org-scoped, and changes to it live as structured rows. Adding a rule means inserting a row in the dashboard, not redeploying the platform.
What the PR shows
Section titled “What the PR shows”A pull request that passes the check shows a single green status from Greenlight and is mergeable through the normal source-control flow. A pull request that fails shows the same status with a structured reason that the agent reads and acts on:
✗ greenlight/policy-check Failed (2/4 checks) • secret-scanning: API key found in src/integrations/snowflake.ts • org-policy/approved-base-images: base image not on the allow-list
Status: merge blockedThe dashboard’s Pipeline tab on each app detail page shows every run with its per-check verdict, the OPA decision JSON, and a link to the raw logs.

What a policy looks like
Section titled “What a policy looks like”Policies are structured data, not free-form scripts. A representative base-image policy:
id: approved-base-imageskind: deny_ifdescription: Containers must use an approved base image.match: resource: dockerfile field: from not_in: - ghcr.io/shiftengineering/node:20-alpine - ghcr.io/shiftengineering/python:3.12-slimon_violation: status: failed message: "Base image not on the approved list."The agent can read the active policy set at any time via the getPolicies MCP tool — so it can fix violations on the first try instead of guessing.
What happens on failure
Section titled “What happens on failure”- The status goes red. The PR comment includes the structured failure reason.
- The agent reads the failure. Either from the PR comment or by calling
getPoliciesto compare its diff against the active rules. - The agent fixes and pushes. Same branch, same pull request. The check re-runs automatically.
- The status goes green. The PR becomes mergeable. Merging triggers deployment.
The Greenlight GitHub App
Section titled “The Greenlight GitHub App”Greenlight talks to your source-control system through the Greenlight GitHub App, which scopes access to a specific GitHub organization and specific repositories. GitLab and Bitbucket will follow the same App-based pattern; GitHub is the supported provider today.
The App is responsible for:
- Creating repositories when an agent calls
registerApp. - Opening pull requests on behalf of agents (the PR’s author is the bound user; the App is the source).
- Posting the single Greenlight Review and Policy Check status on every PR, after Greenlight verifies the scanner evidence and runs the policy engine.
- Reading metadata Greenlight needs to display the app’s status and history in the dashboard.
The App does not have admin permissions on your GitHub organization, push to main, or modify branch-protection rules outside the repositories Greenlight created.
Installing it
Section titled “Installing it”- Start from the dashboard. Navigate to Admin → Source control and click Install GitHub App. You’ll be redirected to GitHub’s App install flow.
- Pick the target organization. Install the App on the GitHub organization that will host your Greenlight-managed repositories.
- Choose repository scope. Greenlight needs to create repositories, so install with “All repositories” or with the + Create new repositories permission. Existing-repo adoption is a separate post-install workflow.
- Confirm permissions. GitHub lists the permissions the App asks for — they map to the responsibilities above; no admin or org-owner permissions are requested.
- Verify in the dashboard. Back in Greenlight, the Source control page should show the App as installed with a green checkmark.
Reinstalling, replacing, or moving the App
Section titled “Reinstalling, replacing, or moving the App”The install isn’t a one-way door. Settings → Source control supports three lifecycle operations, all restricted to org admins and all audit-logged:
- Reinstall on the same org. If the App was uninstalled, installing it again reconnects automatically — Greenlight detects the new installation and verifies it can still reach every managed repository. Any repos the new install can’t see (for example, a “selected repositories” install missing entries) are flagged for you rather than silently skipped, and a Verify access action lets you re-check on demand.
- Re-create the App. If the App was deleted on GitHub, its key was compromised, or your Greenlight URL changed, an admin action re-runs the App creation flow and rotates Greenlight’s stored App credentials to the new App. Webhooks from the new App verify immediately — no restart. Greenlight never deletes the old App on GitHub; once the replacement is working, remove the old one yourself.
- Migrate to a different GitHub org. Install the existing App on the target org (Greenlight records it as a pending target without disturbing the current connection), transfer the managed app and plugin-marketplace repositories in GitHub, then run the migration from settings. A preview shows exactly which repositories will be re-pointed before anything changes, and the migration only completes once every repo is reachable under the new org — then all coordinates move in one step and app-repository branch protection is re-verified. Marketplace visibility and automatic updates carry over at the new coordinates, and deployed apps keep serving throughout.
Branch protection
Section titled “Branch protection”Greenlight creates new repositories with branch-protection rules pre-configured: main requires the single Greenlight Review and Policy Check status to be green before merge, and force-push to main is disabled. There are no human reviewers in the loop — the scanners and policy engine behind that one status are the review. The rules are visible and editable in GitHub’s branch-protection UI; Greenlight does not silently reset them.
The default path is for Greenlight to create new repositories for every app. Bringing an existing repository under Greenlight governance — repo adoption — is a more deliberate workflow, since the existing history needs a one-time policy scan and existing branch protection has to be reconciled; ask in your install for the adoption playbook.
What’s in a Greenlight-managed repo
Section titled “What’s in a Greenlight-managed repo”A Greenlight-managed repo has the same shape as any other repo, plus:
- A
greenlight.ymlat the root withapp_id, requireddocsmetadata, and the declaredworkloads/resources/grants/envblocks. Env-var values are set via MCP; everything else is declared in the file. - A pre-commit hook (optional) that runs the same scanners the policy check runs, so the agent gets fast feedback.
- A GitHub Actions workflow Greenlight installs and updates, which runs the scanners and uploads their evidence. Greenlight verifies that evidence, runs the policy engine, and posts the resulting status — the workflow itself doesn’t decide the outcome.
The developer and the agent both treat the repo as a normal Git repo. Policy enforcement happens through PR statuses, not hidden tooling.