Key Management Guide
DiscussionBridge uses Discourse API keys to publish, sync, diagnose, and recover companion topics. Treat keys as operational credentials.
Key Roles
Section titled “Key Roles”Use separate keys when possible:
- publishing key: normal
publish-new,sync-existing, andpublish-and-syncruns - diagnostics key: setup checks with
check-discourse - recovery/admin key: rare repair operations that need broader authority
For Alpha, the practical model is:
- use a granular publishing key when it can create topics/posts, read linked topics/posts, update managed first posts, update topic metadata, update tags, and unlist when needed
- use a global/admin-capable diagnostics key when granular keys cannot read the site metadata or reconciliation endpoints needed by
check-discourse
Established product rule: when documenting or requesting a granular publishing key, provide the exact Discourse scope settings. Do not describe the publishing key as “similar”, “roughly”, or “mostly” once a product key model has been settled.
Discourse API keys have two independent controls:
- User Level:
All UsersorSingle User; - Scope:
Global,Read-only, orGranular.
With All Users, Discourse allows the request to act on behalf of the username
sent in Api-Username. With Single User, the key is bound to the selected
user. Scope separately controls which endpoints/actions are available. See
Discourse Meta: Create and configure an API key.
Discussion Bridge now has preferred request-actor controls:
- CLI
--post-as; - environment
DISCOURSE_POST_AS; publishOnBuildlane/defaultpostAsorpostAsEnv.
Legacy --api-username, DISCOURSE_API_USERNAME, apiUsername, and
apiUsernameEnv remain compatible fallbacks. Actor precedence is explicit/lane
postAs, named postAsEnv, DISCOURSE_POST_AS, then legacy API-username
controls. The selected actor is sent as Discourse Api-Username.
When Discourse supports or confirms granular diagnostics/read scopes for the required endpoints, move to a two-key model:
- granular publishing key for runtime sync
- granular diagnostics/read key for setup checks
Required Publishing Capabilities
Section titled “Required Publishing Capabilities”The publishing key needs enough permission to:
- create topics and posts in the target category
- read existing linked topics and posts
- update the managed first post
- update topic title/category/tag metadata when enabled
- apply tags or create tags when the lane requires it
- unlist topics when
--unlistis used
On typical Discourse installs, retitling replied topics and changing listing status can require a staff or moderator-capable user.
Use this exact granular publishing/runtime key scope set unless a new feature explicitly requires a documented change:
categories list show
tags list
topics write update read status
posts edit list
search showThis is the settled runtime publishing key model used for Discussion Bridge-style publishing and sync. Diagnostics/setup work stays on the diagnostics key.
Allowed parameters from the Discourse granular key UI:
categories show id: any parameter
posts edit id: any parameter
search show q: any parameter page: any parameter
topics write topic_id: any parameter
topics update topic_id: any parameter category_id: any parameter
topics read topic_id: any parameter external_id: any parameter
topics status topic_id: any parameter category_id: any parameter status: any parameter enabled: any parameterRequired Diagnostics Capabilities
Section titled “Required Diagnostics Capabilities”check-discourse is read-only, but useful diagnostics may require endpoints that granular keys cannot always read.
It may inspect:
/site/settings.jsonfor client-visible authoring limits/site.jsonfor user-specific capabilities such as tag permissions/categories.jsonfor category existence/tags.jsonfor tag inventory/embed/info?embed_url=...for existing embedded-topic reconciliation- exact URL search as a fallback reconciliation check
If a granular key receives 403 for these endpoints, use one of these fallbacks:
- provide explicit CLI/env limits for title/body/tag preflight
- run
check-discoursewith a diagnostics key - manually verify the Discourse setting and record it in deployment docs
Environment Variables
Section titled “Environment Variables”Runtime publishing:
DISCOURSE_POST_AS=discussbridge-botDISCOURSE_API_USERNAME=discussbridge-botDISCOURSE_API_KEY=publishing-keyPrefer DISCOURSE_POST_AS. Keep DISCOURSE_API_USERNAME only where a current
installation still relies on the compatibility fallback.
Optional diagnostics:
DISCOURSE_DIAGNOSTICS_API_KEY=diagnostics-keyOptional explicit limits:
DISCOURSE_TITLE_MIN_LENGTH=15DISCOURSE_MAX_TOPIC_TITLE_LENGTH=255DISCOURSE_MAX_POST_LENGTH=32000DISCOURSE_MAX_TAGS_PER_TOPIC=5DISCOURSE_MAX_TAG_LENGTH=20Storage
Section titled “Storage”Do:
- store keys in a protected credential vault
- store deployment secrets in the hosting provider’s encrypted environment settings
- keep local shell variables session-scoped when testing
- rotate keys after accidental exposure
- keep key filenames descriptive enough to identify purpose and date
Do not:
- commit API keys
- paste real keys into docs, issues, PRs, screenshots, or build logs
- put production keys in example
.envfiles - reuse personal admin keys for routine automation
Example filename convention:
discussionbridge-forum-discussbridge-bot-publishing-granular-key-YYYYMMDD.txtdiscussionbridge-forum-discussbridge-bot-diagnostics-key-YYYYMMDD.txtCredential File Templates
Section titled “Credential File Templates”Use the same structure for every stored Discourse API key. Keep the human-readable purpose and scope above the key value.
Whenever setup instructions ask an operator to create a key, present the matching metadata block together with the key description, user, scope, and granular permissions. Copy that metadata into the respective protected credential file above the secret value. The manual and setup interaction show the placeholder only; they never show or request the real key.
Publishing Granular Key File
Section titled “Publishing Granular Key File”Purpose: Runtime publishing granular keyUse: publish-new, sync-existing, publish-and-sync, check-discourse basic limitsBot user role: Admin currently; intended future runtime posture is non-admin or least-privilegeKey user level: Record All Users or Single User; prefer Single User for a fixed runtime actorKey scope: GranularOperational rule: Use this to validate the minimum permissions needed for normal bridge publishing.
Description{site-or-project} publishing granular key
Key selected user{bot-username when User Level is Single User; not applicable for All Users}
Request actor{resolved postAs / Api-Username}
User Level{Single User or All Users; if Single User, record the selected user}
ScopeGranular
Scopescategories:listcategories:showposts:editposts:listsearch:showtags:listtopics:writetopics:updatetopics:readtopics:status
Key{paste key here}Diagnostics Key File
Section titled “Diagnostics Key File”Purpose: Diagnostics/setup keyUse: check-discourse onlyBot user role: AdminKey user level: Record All Users or Single User and the selected user/actor relationshipKey scope: Global or admin-read capableOperational rule: Do not use in CI/build unless explicitly intended
Description{site-or-project} diagnostics key
Key selected user{admin-bot-username when User Level is Single User; not applicable for All Users}
Request actor{resolved postAs / Api-Username used for diagnostics}
User Level{Single User or All Users; if Single User, record the selected user}
ScopeGlobal or admin-read capable
Permissionscheck-discourse only; global or admin-read capability as required by setup checks
Key{paste key here}Leak Paths
Section titled “Leak Paths”Keys can leak through:
- committed
.envfiles - command history copied into issues or chat
- build logs that print environment variables
- screenshots of terminal windows or admin pages
- CI/CD secret misconfiguration
- shared machines or synced folders with broad access
- package fixtures or demo repos that accidentally include real credentials
If a key leaks, revoke it in Discourse, create a replacement, update the deployment secret, and rerun check-discourse.
Rotation
Section titled “Rotation”Rotate keys when:
- a user leaves the project
- a key is pasted into an unsafe place
- permissions change from global to granular
- the bot user’s role changes
- moving from Alpha testing to a public release
For rotation:
- Create the replacement key.
- Update local or hosting secrets.
- Run
check-discourse. - Run a dry-run publish or sync.
- Revoke the old key.
- Record the rotation date in private ops notes.
Delegated Posting Investigation
Section titled “Delegated Posting Investigation”postAs is now the implemented preferred actor selector. It changes the
Api-Username request actor; it does not transfer ownership of an existing
topic. Whether that actor may differ from the key’s selected user depends on the
key’s User Level, while endpoint authority depends on Scope.
Before a write, record and verify the key User Level, its selected user when
Single User, the resolved postAs/Api-Username actor, the key
Scope/granular permissions, and the actor’s category/tag/staff permissions.
Live CLI output should show Post as: USER; check-discourse reports
Request actor.
Nonhuman Identity Inventory
Section titled “Nonhuman Identity Inventory”Across connected forums, no two nonhuman accounts may have the same—or visually ambiguous—username/display-name combination. Encode both role and origin system.
| Origin | Candidate username | Candidate public name |
|---|---|---|
| Discussion Bridge Forum | editorbridgeforum |
Discussion Bridge Forum Editor |
| Citizen Activist Network Forum | editorcanforum |
CAN Forum Editor |
Discourse normalizes username case. Check the exact final username against each
site’s length rules and availability before creation. Astro-origin publishing
accounts should identify the originating site/brand rather than only the
destination forum. Preserve established obbba-bot as the OBBBA source
identity.
Create a special-admin custom group on each forum as the visible inventory
home for nonhuman admin/service accounts. Group membership is organizational
only: it does not grant Discourse admin status, category permissions, or API
rights. Assign those separately.
Build Logs
Section titled “Build Logs”The CLI should never print key values. Operators should also avoid commands that echo environment variables near build output.
Safe:
npx astro-discussion-bridge check-discourse --discourse-url https://forum.example.com --category-id 5Unsafe:
echo $DISCOURSE_API_KEYWhen reporting support issues, include command, mode, Discourse URL, category ID, tags, page URL, and sanitized error output. Do not include API key values.