Skip to main content

Security

Documentation Map

Security

Auth Model

  • primary operator auth:
    • session cookie pm_session
  • supported auth-related integrations:
    • Gitea OAuth
    • GitHub OAuth
    • GitLab OAuth
    • OIDC
  • development auth:
    • optional dev-login path
    • only appropriate when explicitly enabled

Access Control

  • product writes are expected to run through authenticated operator paths
  • integration configuration and revoke/bootstrap flows are privileged
  • recovery actions such as restore, freeze, and unfreeze require explicit operator intent
  • MCP is not a bypass path; it rides the same product contract and should remain auditable

Sensitive Data Types

  • provider OAuth client secrets and tokens
  • Plane API token and webhook secret
  • approval shared secret
  • runtime and n8n webhook targets
  • database credentials
  • session secret

Secret Model

  • secrets are expected in runtime environment or external secret storage
  • secrets must not be committed into the repository
  • this repository documents required secret names but does not carry secret values
  • standalone mode and integrated mode must both keep repository history free of secret material

Secret And Credential Classes

ClassTypical valuesAllowed source in standalone modeAllowed source in integrated modeCurrent Mission Control persistenceRotation owner
session and database bootstrapSESSION_SECRET, DATABASE_URLruntime environment or external secret storage injected into the processruntime environment or external secret storage injected by the shared platform layernot persisted by Mission Controlplatform or host operator
provider OAuth application credentialsGITEA_OAUTH_CLIENT_SECRET, GITHUB_OAUTH_CLIENT_SECRET, GITLAB_OAUTH_CLIENT_SECRET, OIDC_CLIENT_SECRETruntime environment, or operator-saved setup state when the current settings flow stores them for the active instanceshared platform runtime injection; no Fabric-side write-back into the repomay be mirrored in operator-controlled _control/*_oauth.json state for active setup flowsoperator or platform operator
provider user or automation access tokensGITEA_TOKEN, GITHUB_TOKEN, GITLAB_TOKEN or OAuth access tokensruntime environment and operator-controlled OAuth login stateruntime environment, platform secret injection, or fresh operator re-authorization when user context is requiredoperator OAuth state may store active access tokens outside the repooperator for user tokens; platform operator for automation tokens
workspace integration credentialsPLANE_API_TOKEN and project-scoped saved provider/Plane credentialsruntime environment or operator-saved workspace/project integration recordssame as standalone until a shared attachment contract exists; no automatic takeover is implementedPlane and provider bridge records may store credentials in workspace metadata todayoperator
callback and webhook shared secretsPLANE_WEBHOOK_SECRET, CLAWLEDGER_APPROVAL_SHARED_SECRETruntime environment or external secret storage injected into runtimeruntime environment or external secret storage injected by the shared layernot persisted by the repo; consumed from runtime settingsplatform or host operator
outbound protected webhook targetsN8N_OPERATOR_WEBHOOK_URL, OPENCLAW_RUNTIME_DISPATCH_WEBHOOK_URL plus upstream auth material outside this repodeployment-specific runtime environment or external secret storagedeployment-specific runtime environment or external secret storageURL may be configured in runtime settings; upstream auth stays outside this repoplatform or host operator

Mode Boundary

  • standalone mode:
    • the operator or host owner is responsible for secret sourcing, runtime injection, and revocation
    • Mission Control may persist some operator-entered provider or workspace credentials in runtime state outside git history
  • integrated mode:
    • Fabric may discover that Mission Control needs these secret classes, but Fabric does not currently push or rotate them
    • the shared platform layer may inject runtime secrets, but Mission Control does not yet implement a dedicated integrated credential handoff API
    • when user-context provider access is required, operator re-authorization remains the expected path

Mode Transition Rules

  • the move from standalone to integrated must not silently regenerate OAuth apps, shared secrets, or provider tokens
  • an integrated deployment may reuse existing standalone secret values only through explicit operator-controlled runtime injection or re-entry
  • Mission Control does not treat Fabric as a secret source of truth today
  • if a credential source changes, the old value must be revoked or rotated by the responsible operator; Mission Control does not auto-rotate it
  • repo-local files, committed examples, and fabric manifests must never become the only source of an actual secret value

High-Risk Interfaces

These must not be left open or unauthenticated:

  • /api/v1/auth/* configuration and callback-adjacent flows
  • Plane integration and webhook routes
  • provider integration write routes
  • restore, snapshot, freeze, and unfreeze routes
  • approval callbacks
  • runtime dispatch bridges

Webhook And Callback Contract

SurfaceDirectionAuth mechanismHeader or secret transportCompatibility fallbackFailure codeAllowed caller class
/api/v1/projects/{project_id}/integrations/plane/webhookinboundshared secretX-Plane-Webhook-SecretX-Webhook-Secret and ?secret= are still accepted for legacy callers; new registrations should use the dedicated Plane header403 when PLANE_WEBHOOK_SECRET is configured and does not matchconfigured Plane instance
/api/approvals/clawledgerinboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/approvals/jhf-spindle/pendinginboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/approvals/clawledger/pendinginboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/v1/approvals/jhf-spindle/pendinginboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/v1/approvals/clawledger/pendinginboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/approvals/clawledger/syncinboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/approvals/clawledger/{project_id}/{task_key}/decisioninboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
/api/approvals/clawledger/decisioninboundshared secretX-ClawLedger-Tokennone401 when CLAWLEDGER_APPROVAL_SHARED_SECRET is configured and does not matchconfigured approval system
OPENCLAW_RUNTIME_DISPATCH_WEBHOOK_URLoutbounddeployment-specific protected targetoutside this reponone in this repositoryupstream-definedconfigured runtime bridge
N8N_OPERATOR_WEBHOOK_URLoutbounddeployment-specific protected targetoutside this reponone in this repositoryupstream-definedconfigured n8n operator target

Inbound Security Rules

  • inbound shared-secret checks use constant-time comparison
  • missing or mismatched Plane webhook secrets are treated as 403
  • missing or mismatched ClawLedger callback secrets are treated as 401
  • unauthenticated compatibility fallbacks are not allowed; only the documented alternate transport keys are accepted
  • new integrations should prefer explicit headers over query-string secrets

Interfaces That Must Never Be Open

  • provider bootstrap/configure/revoke routes
  • restore and destructive recovery actions
  • runtime dispatch or control hooks
  • secrets/config mutation paths

Rotation And Revocation Boundaries

  • operator-managed credentials:
    • provider OAuth setup saved through Settings
    • workspace Plane/provider tokens saved through Settings
    • revoke, replace, or re-authorize through the operator path before considering the old credential dead
  • platform-managed credentials:
    • database credentials
    • session secret
    • host-injected webhook shared secrets
    • rotate outside the repository and restart or redeploy the runtime
  • explicit non-goals:
    • no repo-driven rotation
    • no Fabric-triggered secret mutation
    • no silent credential copy from standalone storage into a future integrated deployment

Automation Boundaries

The following must not be allowed as uncontrolled automation from Fabric or other external orchestrators:

  • direct secret injection
  • direct database mutation
  • destructive project/task deletion without operator path
  • restore/freeze/unfreeze without operator review
  • provider auth bootstrap or revoke
  • unaudited runtime dispatch

Risks

  • sync drift across Gitea, Mission Control, and Plane
  • provider takeover through misconfigured OAuth/bootstrap paths
  • approval or webhook spoofing if secrets are weak or absent
  • operator confusion if read-only discovery endpoints are mistaken for safe write surfaces

OAuth and Why It Exists Here

OAuth is relevant in this repository because Mission Control integrates with hosted/self-hosted Git providers and optional OIDC login flows.

It is not optional for those provider-backed use cases, but it is not required for every local-only development path.

OAuth Decision Rules

OAuth is required when:

  • external users interact with the system
  • a multi-tenant scenario exists
  • access comes from outside the platform network
  • a provider requires user-context authorization

OAuth is not required when:

  • communication is strictly internal service-to-service
  • communication is Fabric-driven and does not need user context
  • a pure read-only health or discovery surface is being consumed

License: AGPLv3

Helpifyr: https://helpifyr.com