Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ export default defineConfig({
link: "/guides/infrastructure/infrastructure-reference",
},
{ text: "Mint Administration", link: "/guides/infrastructure/mint-administration" },
{
text: "App Permission Rollout",
link: "/guides/infrastructure/app-permission-rollout",
},
{ text: "Standalone Mint", link: "/guides/infrastructure/standalone-mint" },
{ text: "Private Repositories", link: "/guides/infrastructure/private-repositories" },
{ text: "Tracing Reference", link: "/guides/infrastructure/distributed-tracing" },
Expand Down
50 changes: 50 additions & 0 deletions docs/contributing/mintcore.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,56 @@ boundary.
Each load site constructs the appropriate accessor and passes it to
`NewHandler`. Tests can pass any `PEMAccessor` implementation.

## Adding a permission to a role

A role's GitHub App permissions are declared in three places that must change
together in one PR:

| Declaration | File | Note |
|-------------|------|------|
| Mint role map | `canonicalRolePermissions` in `internal/mintcore/github.go` | What the mint requests when minting a token |
| GCF embed copy | `internal/dispatch/gcf/mintsrc/mintcore/github.go.embed` | Byte-identical copy; `hack/lint-mint-embed-sync` enforces it |
| App manifest | `AgentAppConfig` in `internal/forge/github/types.go` | What `fullsend github setup` asks GitHub to create the App with |

The parity tests in `internal/forge/github/types_test.go`
(`TestAgentAppConfig_CoderMatchesMintcorePermissions` and its siblings — today
`e2e`, `scribe`, `coder` and `fix` have one) fail if the manifest and the mint
role map disagree, so the edits land together or CI is red. If the role you are
changing has no parity test yet, add one in the same PR.

### The backward-compatibility rule

A permission that existing installations have not granted **must** be added to
`optionalRolePermissions` in the same PR. GitHub rejects the entire
installation-token request with `422` when any requested permission is
ungranted — there is no partial downscope — so without the optional entry every
mint for that role fails on the day the mint deploys, for every installation
that has not accepted the App update yet.

`effectiveInstallationPermissions` applies the distinction just before the token
POST: it compares the requested map with the installation's granted map, drops
ungranted permissions listed in `optionalRolePermissions` (logging
`installation permissions not granted: … dropped=…`), and returns
`ErrRequiredPermissionsMissing` for any other ungranted permission, which the
handler surfaces as `422`. When the installation lookup carries no `permissions`
map at all (or an empty one), the full requested set is sent and GitHub validates it.

The optional entry is **temporary**. Once the mint logs stop showing drops for
the permission, remove it in a follow-up PR; the permission then behaves like
every other one in the role's map. The entry stays keyed by role — today
`optionalRolePermissions` has entries for `coder` and `fix`, both for
`packages`.

### Commit conventions

Adding a permission is a `BREAKING CHANGE` for users: App owners must update the
App registration before installations can grant it. The commit subject and PR
title carry the `!` suffix (see `COMMITS.md` at the repository root).

The operator side of the change — updating the App registration, deploying the
mint, chasing installation owners to accept — is
[Rolling out a GitHub App permission](../guides/infrastructure/app-permission-rollout.md).

## Interfaces vs accessors

Mintcore uses two patterns for dependency injection:
Expand Down
1 change: 1 addition & 0 deletions docs/guides/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Guides for organization owners and repository administrators who manage fullsend
Advanced guides for platform operators who deploy and manage the GCP-side infrastructure (token mint, WIF, secrets).

- [Mint service administration](infrastructure/mint-administration.md) — Deploying and managing the token mint (GCP or Cloudflare)
- [Rolling out a GitHub App permission](infrastructure/app-permission-rollout.md) — Adding a permission to a mint role without breaking installations that have not accepted it yet
- [Standalone mint](infrastructure/standalone-mint.md) — Running the token mint as a standalone HTTP server without GCP
- [Infrastructure reference](infrastructure/infrastructure-reference.md) — Token mint, WIF, and secrets deployment details
- [Enabling fullsend on private repositories](infrastructure/private-repositories.md) — Additional guardrails and configuration for private repos
Expand Down
7 changes: 7 additions & 0 deletions docs/guides/getting-started/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ fullsend github set "$OWNER/$REPO" FULLSEND_GCP_REGION global
| `FULLSEND_GCP_PROJECT_ID` | Repo secret | GCP project ID where Agent Platform is enabled | `my-gcp-project` |
| `FULLSEND_GCP_WIF_PROVIDER` | Repo secret | Full WIF provider resource name for OIDC authentication | `projects/123456789/locations/global/...` |


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] spurious blank line

The diff adds a stray blank line between the GitHub table and the ### GitLab heading (two blank lines instead of one). The rest of the file uses exactly one blank line between a table and a heading.

Suggested fix: Remove the extra blank line so there is a single blank line between the table and ### GitLab, matching the rest of the file.

### GitLab

For GitLab repos, re-run `repos install` with updated values to converge configuration:
Expand All @@ -41,6 +42,12 @@ fullsend repos install -f repos.yaml "$OWNER/$REPO" \
| `FULLSEND_GCP_PROJECT_ID` | CI/CD secret | GCP project ID for inference | `my-gcp-project` |
| `FULLSEND_GCP_WIF_PROVIDER` | CI/CD secret | WIF provider resource name for inference | `projects/123456789/locations/global/...` |

## Accepting a GitHub App permission update

GitHub emails organization owners when a fullsend App requests updated permissions — for example when the coder App starts asking for `packages:read`. Go to your org → **Settings** → **Third-party Access** → **GitHub Apps** (`https://github.com/organizations/<org>/settings/installations`), click **Configure** on the App, and use the **Review request** banner to accept. Only org **owners** see the banner; members see nothing.

Agents keep working while the request is pending: during a rollout the mint mints tokens without the pending permission and logs the gap, so nothing breaks before you accept — accepting is what unlocks the capability the permission covers. See [the installation-owner step](../infrastructure/app-permission-rollout.md#installation-owner-accept-the-update) of the rollout runbook.

## Syncing workflow templates

After upgrading the fullsend CLI, re-run `github setup` to update the workflow file for a single repo:
Expand Down
Loading
Loading