greenlight.yml
Reference
Every Greenlight-managed repository has a greenlight.yml at the root. It is the contract for what the deployed pod sees: identity, documentation, and declared infrastructure (workloads, resources, grants, and env-var names). The agent edits it with ordinary file tools and opens a PR; on merge, the reconciler applies it. Env-var values are written separately through envSet and never live in this file.
The agent reads app_id from this file on a fresh clone, then calls getApp for everything else.
A minimal example
Section titled “A minimal example”schema_version: 1app_id: app_k9x2m3pslug: expense-trackerowner: jane@contoso.com
docs: summary: Reimbursement tracker for finance ops. purpose: Replace the shared spreadsheet finance currently uses. architecture: | Single Node.js web service. Postgres for records. SSO-gated; UI is shadcn + Tailwind.registerApp seeds this file with app_id, the docs block, the Greenlight pipeline workflow, and a .gitignore — plus commented-out scaffold for the workloads, resources, grants, env, and tags blocks below. Those scaffold comments link back to these public docs pages so a builder agent in the customer repo never needs the private Greenlight monorepo. No Dockerfile is seeded; the agent authors it for the app’s stack in the first code PR. The app stays in registered state, with no infrastructure, until that first PR declares its workload and merges.
A full example
Section titled “A full example”schema_version: 1app_id: app_k9x2m3pslug: expense-trackerowner: jane@contoso.com
docs: summary: Reimbursement tracker for finance ops. purpose: Replace the shared spreadsheet finance currently uses. architecture: Single Node.js web service backed by Postgres.
workloads: web: kind: web dockerfile: Dockerfile port: 8080 routes: ['/*']
resources: - kind: postgres name: db - kind: blob name: receipts
grants: - integration: snowflake-prod credential: analytics-read reason: Read the sales mart for the dashboard.
env: - { name: APPROVAL_SECRET, sensitive: true } - { name: FEATURE_FLAGS, sensitive: false }
tags: - finance - productivitySchema
Section titled “Schema”Identity & docs
Section titled “Identity & docs”| Field | Required | Description |
|---|---|---|
schema_version |
yes | Manifest format version. 1 is the only accepted value; written at registration. |
app_id |
yes | Greenlight app identifier; written at registration. |
slug |
no | URL-safe identifier; informational after registration. |
owner |
no | Owning user. |
co_owners |
no | Additional editors. Editors are managed on the app’s Access tab, or with addCoOwner / removeCoOwner; this field is informational. |
created_at |
no | ISO 8601 timestamp; written at registration. |
docs |
yes | Deploy-time app documentation projected into the dashboard (see below). |
The manifest is parsed strictly — a key that isn’t in this reference fails the check rather than being ignored.
Declared infrastructure (applied on merge)
Section titled “Declared infrastructure (applied on merge)”These blocks are the desired state the merge-time reconciler converges to:
workloads— the app’s runnable shape: awebworkload withkind,dockerfile,port, androutes. Omitcompute:unless you have evidence you need more than the baseline; declaring it sets request = limit, so the capacity stays reserved for as long as the app is deployed whether or not the app uses it. Size it against a measured need rather than copying a value from another app: abovecpu: 250mormemory: 512Mithe pull request carries a sizing warning (it never blocks the merge), andgetMetricsreports what the app reserves beside what it actually uses.resources— managed resources bykind(postgres,blob) andname. Provisioning these is what injects their managed env vars (DATABASE_URLfor Postgres;GREENLIGHT_DATA_KEY+GREENLIGHT_PROXY_URLfor blob).grants— the app’s integration access. Each entry names theintegration, thecredential(the IT-registered slug), and an optionalreason. One entry per integration: an app binds exactly one credential to a given system, so a second entry naming an integration already granted is rejected when the pull request is opened. When the app needs a system for two jobs, grant the one credential whose upstream permissions cover both. Auto-approved grants work immediately on merge; the rest land in IT’s review queue while the app deploys. Manifest grants bind the app only — a person’s own access to an integration is requested imperatively viarequestCredentialAccess, never declared here (see Local development). A grant on a user passthrough integration needs nothing more: the app renders for everyone, and each person connects their own account from a Connect button the app shows when a feature needs it.env— the names (andsensitiveflags) of user-controlled env vars. Values are written viaenvSet; every declared name must have a value at merge time or the deploy fails.tags— optional org-wide category labels for the dashboard’s app catalog filter. Free-form, up to 12 tags of 50 characters each; prefer a fitting term from the suggested set (productivity,marketing,finance,project management,games,test) before inventing one.
runtime and build details live in the repo’s Dockerfile and source code, not here.
The docs block is required deploy-time documentation:
docs.summary,docs.purpose, anddocs.architectureare projected intoapps.doc_*after a successful deployment.- The app detail page renders that projection in its read-only “About this app” section.
- App Knowledge is separate and starts empty; owners create entries and agents propose them only when useful context emerges.
Changes to greenlight.yml docs.* update the deployment projection on a successful merge. They do not create or overwrite Knowledge entries.
Policy check
Section titled “Policy check”On every pipeline run, the policy gate validates greenlight.yml: required identity and docs fields, and the manifest blocks above — for example, it rejects an env: entry that collides with a platform-reserved name or a second grants: entry for an integration already granted, and the deploy fails if a declared env: name has no value in the vault. Approved changes are applied by the reconciler on merge.