Open Mission now supports two distinct GitHub access lanes: interactive user login through the web host and unattended GitHub operations performed by the daemon. Those lanes must not collapse into one ambient token model.
This ADR records the deployment-auth model for self-hosted Open Mission and the ownership split between system-scoped GitHub App credentials and Repository-scoped installation trust.
Decision
Open Mission uses one GitHub App per Open Mission installation for unattended GitHub access.
The Open Mission installation authenticates as that GitHub App using deployment-scoped environment variables such as GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY. The daemon uses those credentials to mint short-lived GitHub App installation access tokens on demand.
Repository authorization remains Repository-scoped. A Repository may allow unattended GitHub operations only when it carries a GitHub App installation binding that names the GitHub installation allowed to act for that Repository.
Interactive user actions remain request-scoped and user-authored. Browser login through the Open Mission web host continues to use GitHub OAuth user tokens for user-facing interactive operations such as sign-in, repository discovery, and explicit operator-triggered reads or mutations performed as the logged-in human.
Ownership Split
System-scoped ownership:
- GitHub App deployment credentials
- GitHub App JWT generation
- installation access token minting
- installation token caching and refresh policy
- deployment diagnostics for whether GitHub App auth is configured
Repository-scoped ownership:
- whether a Repository is authorized for unattended GitHub operations
- which GitHub App installation applies to that Repository
- Repository-facing operator guidance when unattended delivery is unavailable
User-session ownership:
- browser OAuth login
- request-scoped user GitHub access token forwarding
- user-authored interactive GitHub operations
This means Open Mission does not use Repository-specific GitHub App credentials. One Open Mission installation owns one GitHub App identity; each Repository decides whether that identity is authorized to act for it.
Deployment Modes
Self-hosted Open Mission:
- the operator or platform admin creates a GitHub App for that Open Mission installation
- the operator configures Open Mission with that app’s deployment credentials
- the operator installs that GitHub App on selected repositories or organizations
Hosted Open Mission:
- the Open Mission service operator owns the shared GitHub App credentials
- customer repositories authorize unattended access by installing that shared GitHub App
Configuration Rules
GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY are deployment secrets. They must not be persisted inside Repository control state, Mission records, or user sessions.
GITHUB_APP_CLIENT_ID and GITHUB_APP_CLIENT_SECRET are separate from the private key. They support GitHub OAuth user login through the web host and do not replace GitHub App installation authentication.
GITHUB_APP_WEBHOOK_SECRET is deployment-scoped verification material for GitHub webhook delivery when webhook-backed synchronization is enabled.
Open Mission config files may describe filesystem roots and non-secret operator settings, but GitHub App private key material remains in environment or equivalent secret storage.
Runtime Rules
The daemon-owned GitHub App token provider is the only owner of installation-token minting behavior.
Adapters such as the GitHub adapter may consume a token provider seam, but they must not own GitHub App private key parsing, JWT signing, or direct secret resolution from process environment.
Repository and workflow behavior must not infer unattended authorization merely from the presence of system-scoped GitHub App credentials. A Repository without an installation binding is not authorized for unattended GitHub delivery.
Consequences
- Open Mission gains one clear unattended GitHub authentication model that does not depend on ambient user OAuth tokens.
- Self-hosted operators configure one GitHub App identity for one Open Mission installation instead of managing Repository-specific secrets.
- Repository truth stays narrow: a Repository stores only its authorization or binding facts, not deployment secrets.
- User OAuth login remains valid for interactive operator actions without becoming the long-lived daemon automation credential.