Skip to content

Unified configuration

Keep configuration non-secret and host-neutral. One strict versioned JSON document contains the verified application and bot identities, explicit read modes and exact scope where selected, typed reusable exact-ID groups, notification and thread-inheritance policy, selected tools, Gateway policy, capability gates, feature-specific scopes, bounded limits, owned local storage roots, runtime settings, and credential-free observability policy. Secret fields contain only external environment or file references; collector headers remain environment references. Never put a bot token, collector header value, Discord name, message data, attachment URL, embed, component, or other Discord content in a configuration document.

Treat a selected configuration as the exclusive policy boundary. Activation must parse and materialize the document directly, resolve only the exact secret references it names, and never mutate process.env. Reject every other populated GUILDCONTROL_* or OTEL_* variable and every undeclared Discord token variable so ambient state cannot silently widen or alter file policy. Tool selection, all-visible read modes, typed group expansion, parent-thread inheritance, and reviewed notification exceptions remain explicit policy choices, never substitutes for Discord permissions, exact mutation targets, planning, approval, confirmation, freshness, operation receipts, or content-free audit gates.

Require readScope.guildMode and readScope.channelMode to normalize to either allowlist or all-visible. An allowlist mode needs at least one effective exact ID; an all-visible mode needs an empty ID array and must be reported as an authority boundary whose future reach follows Discord-side visibility. Treat top-level groups only as typed local aliases for exact guild, channel, user, or role snowflakes. Reject nesting, cross-type references, unknown groups, duplicate effective IDs, noncanonical ordering, and any attempt to use a group name as a Discord object name or write target. Configuration review must classify mode changes and effective expanded scope changes, not only raw array edits.

Load standalone configuration only from a bounded canonical path whose parent contains no symbolic component and whose selected entry is a protected regular file or an explicit final symbolic link to a protected stable regular target owned by the process user or root, with no group or world write access. Permit additional hard links only for this non-secret policy target. Bind the resolved target and stable metadata during inspection and review, reject retargeting or source drift, preserve an explicit selected link during publication, and atomically detach only the selected path when replacing a multiply linked regular file. Creation and replacement additionally require a canonical private directory owned by the process user. Publish through private exclusive temporary files, an exclusive lock, file and directory synchronization, and exact readback. Replacement must retain a recoverable hidden backup and refuse to change the pinned Discord identity. Do not extend this topology relaxation to credential files, webhook capabilities, attachment inputs, or another secret or capability-bearing file.

Load a file-backed bot credential only from an absolute reference that resolves to a bounded stable regular target owned by root or the process user, with one hard link and no group or world write access. Permit a projected-secret symlink at the configured path, but open the resolved final target without following another link and verify path and metadata stability around one bounded UTF-8 read. Reject an ambient canonical token alongside a file reference instead of selecting a fallback. Never include bot credential bytes in errors, reports, logs, telemetry, configuration, or connector-managed persistent state.

Managed profiles use the same complete policy contract in a private per-user directory. Unsupported schema versions fail closed and no environment-policy compatibility shape is accepted. Profile removal must require exact confirmation and move a validated profile into private recoverable trash; it must never claim to revoke or modify the external Discord credential. Restore only the newest valid generation and only when no active profile has that name.

Canonical source: SECURITY.md

Documentation generated for guildctl@0.3.1. Canonical source and edit history remain in the public repository. GuildControl is an independent project and is not affiliated with or endorsed by Discord Inc. Discord is used only to identify the platform that GuildControl connects to.