Guild Templates
Keep native Guild Template inventory behind its own audit toggle and exact guild allowlist. The allowlist must remain a subset of any configured read-guild scope. Require verified application and bot identities, an exact guild and owner, exact connector membership, complete bounded roles and direct guild channels, a complete bounded template inventory, and effective guild-level MANAGE_GUILD before returning an inventory or plan.
Keep template codes transient inside the REST and Guild Template service layers. Project raw Discord responses before forming an MCP result. Return only a process-keyed opaque reference, bounded timestamps and usage state, creator user ID without a profile, metadata character counts, count-only snapshot structure and permission risks, dirty state, count-only live guild structure, and explicit privacy and snapshot limitations. Never return a code, use URL, name, description, creator profile, guild name, role or channel name, channel topic, icon hash, serialized source guild, raw response, or unknown field value. Do not add template use, guild creation from a template, import, export, restore, arbitrary code lookup, or a code-bearing MCP schema.
Treat a Guild Template as a reusable snapshot for future guild creation, not as a backup. Surface that it does not preserve original IDs, members, messages, audit history, integrations, or application-owned resources and that Discord may omit unsupported channel types, managed roles, and guild features. Validate every serialized snapshot under strict depth, node, string, role, channel, and overwrite bounds. Count unknown fields without returning values. Bind the complete private snapshot into freshness while returning only count-based live and target structure. Keep managed roles out of advisory identity drift while retaining them in count-only structure and risk evidence. Treat structural drift as advisory because Discord's snapshot is partial, and use Discord's explicit clean dirty-state only for a no-op synchronization decision. Permit read-only inventory to count unknown top-level template fields, but fail closed before change planning because their privacy-discarded values cannot be freshness-bound. Retain and privately bind unknown serialized-snapshot values while exposing only their count.
Keep create, synchronize, metadata-update, and delete actions behind a second capability gate and the same exact guild audit scope. Do not add an immediate-call path. Every non-create action must accept only an opaque process-local reference. Reject template URLs in audit reasons before any Discord read and reject the freshly resolved target code before mutation. Preserve every gate: verified identities, exact scope, complete private inventory and live guild evidence, strict action-specific normalization, process-keyed plan binding, signed interactive confirmation, write-aware client approval, final fresh-plan match, atomic one-shot operation-key reservation, pending content-free activity, one non-retried mutation, strict returned-capability validation, and an exact complete-inventory transition readback. A client without MCP elicitation must not execute a Guild Template change.
Treat Guild Template creation and synchronization as non-atomic snapshots. Discord exposes no conditional mutation that binds the reviewed live guild to the resulting snapshot. Require an authoritative clean response plus exact full-inventory readback, but do not represent that evidence as proof of complete fidelity with the reviewed guild or a future guild created from the template. Prevent concurrent guild administration and use an exclusive administration window for high-risk snapshots. A non-clean response or readback is an uncertain outcome, spends the operation key, and retains the guild quarantine.
Discord does not document audit-log-reason support for Guild Template endpoints. Validate and bind the reason into the reviewed plan and signed confirmation, but do not send an undocumented audit-log header. Never suggest that the reason entered Discord's audit log.
A known Discord 4xx refusal before a mutation acknowledgement may be classified as failed. Treat rate limiting, transport failure, Discord server failure, malformed success, returned-capability or metadata mismatch, failed complete-inventory readback, or any otherwise indeterminate post-reservation state as uncertain and potentially completed. A mutation with exact successful readback whose local completion record fails is known completed but remains quarantined. Spend every reserved key after every outcome, retain a permanent same-guild ambiguity barrier inside the service instance, and never retry, compensate, restore, or infer a result from template names. The production facade also acquires a durable exact guild template-collection claim, so connector processes sharing the activity-state root exclude overlapping changes and retain the claim after uncertainty or failed completion recording.
Guild Template activity and operation records may contain only the exact guild ID, optional opaque template reference, action, plan digest, operation-key hash, timestamps, fixed verification and outcome values, activity ID, and sanitized error category. Never persist template codes, URLs, names, descriptions, creator profiles, source snapshots, guild or resource names, permission evidence, audit reasons, raw operation keys, raw Discord responses, or transport causes.
Canonical source: SECURITY.md
Documentation generated for guildcontrol@0.0.0. 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.