Declarative plugin configuration
Server operators can keep plugin versions, settings, required secret
references, and server pipelines in source control, preview drift, and apply
the desired state with the backend's mfctl command.
The current manifest API is multiforum.gennit.dev/v1alpha1.
What the manifest owns
Plugin reconciliation is additive. A plugin omitted from the manifest is not disabled or uninstalled. For a listed plugin, the manifest manages only the exact version it names; settings and secret references are optional.
Pipeline ownership is deliberately stricter:
- omit
pipelinesto leave server pipelines unmanaged; - use
pipelines: []to manage the server pipeline list as empty; - provide a list to manage the complete server pipeline list.
This distinction prevents a plugin-only manifest from deleting hand-managed
pipelines while still allowing an infrastructure repository to own the full
pipeline policy. Generated effectiveAt and policyId values stay
server-owned unless the manifest explicitly supplies them.
Example manifest
Unlike the admin pipeline editor, the declarative API format uses pluginId
for steps.
{
"apiVersion": "multiforum.gennit.dev/v1alpha1",
"plugins": [
{
"pluginId": "security-attachment-scan",
"version": "0.5.1",
"enabled": true,
"settingsJson": {
"serviceUrl": "https://security-scan-service.example.run.app",
"blockOn": "malicious",
"onError": "block"
},
"secretRefs": [
{
"key": "SCAN_SERVICE_API_KEY",
"valueFrom": "env:SCAN_API_KEY"
}
]
}
],
"pipelines": [
{
"event": "downloadableFile.created",
"applicability": "NEW_FILES_ONLY",
"stopOnFirstFailure": true,
"steps": [
{
"pluginId": "security-attachment-scan",
"version": "0.5.1"
}
]
}
]
}
Keep the manifest in source control. Keep secret values in the local environment or CI secret store.
Plan and apply
Run mfctl from a backend checkout with its dependencies installed:
export MULTIFORUM_GRAPHQL_URL=https://forum.example/graphql
export MULTIFORUM_ACCESS_TOKEN=your-existing-user-access-token
export SCAN_API_KEY=resolved-only-at-runtime
pnpm mfctl plugin-config plan --manifest examples/plugin-configuration.json
pnpm mfctl plugin-config apply --manifest examples/plugin-configuration.json
The user token must belong to an existing user with canManagePlugins.
plan is read-only and does not resolve or transmit plugin secret references.
apply performs a complete preflight, then installs versions, writes supplied
secrets, updates settings and enabled state, and finally updates managed
pipelines. It stops at the first failure and returns the operations that already
succeeded plus a fresh drift plan.
Secret values are write-only. Because Multiforum cannot compare an existing
plaintext value, supplying a resolution during apply writes it again even
when structural configuration is already in sync. This supports intentional
secret rotation.
Use --endpoint instead of MULTIFORUM_GRAPHQL_URL and --json for
machine-readable output. Exit codes are:
| Code | Meaning |
|---|---|
0 | The plan is in sync, or apply converged successfully. |
1 | Input, request, preflight, apply, or remaining-drift failure. |
2 | Plan succeeded and found drift. |
CI machine identity
For unattended apply, mfctl can obtain a short-lived token through OAuth
client credentials:
export MULTIFORUM_GRAPHQL_URL=https://forum.example/graphql
export MULTIFORUM_OAUTH_TOKEN_URL=https://tenant.example/oauth/token
export MULTIFORUM_OAUTH_CLIENT_ID=stored-in-ci
export MULTIFORUM_OAUTH_CLIENT_SECRET=stored-in-ci
export MULTIFORUM_OAUTH_AUDIENCE=https://api.example
export MULTIFORUM_OAUTH_SCOPE=plugin-configuration:write
pnpm mfctl plugin-config apply --manifest examples/plugin-configuration.json
Allowlist the token's exact sub claim in the backend environment variable
PLUGIN_CONFIGURATION_AUTOMATION_SUBJECTS. For Auth0 client credentials this
is normally <client-id>@clients.
Machine identities are intentionally limited to plugin reconciliation. They do not become Multiforum users and cannot call unrelated administration operations. The OAuth client secret remains in CI and is not stored in Multiforum.
Safety rules
- Review
planbefore applying a pipeline replacement. - Treat a manifest containing
pipelinesas authoritative for the complete server list. - Do not commit resolved secrets or pass them as literal manifest values.
- Pin plugin versions so deployment is reproducible.
- Leave generated rollout IDs and effective timestamps unspecified unless the operator deliberately owns them.
- After apply, exercise a safe fixture and check both the pipeline result and provider health.
The first-party scanner deployment uses this workflow to manage Cloud Run and Multiforum from one release job. See Security attachment scanning.