Application-owned emojis
Keep application-owned emoji inventory behind its own audit toggle and the configuration's pinned application and bot identities. Resolve application scope only from the freshly verified token identity. Never accept a caller-supplied application ID, infer another application, reuse guild-expression scope, or require a guild allowlist, guild permission, or privileged intent.
Project every Discord response immediately to bounded stable emoji metadata and unknown-field counts. Require the application-specific empty role array and a valid uploader object, then discard roles and uploader identity before returning data. Never return or persist image bytes, CDN URLs, uploader IDs or profiles, raw objects, role IDs, or unknown values. Require a complete bounded inventory with unique exact IDs before planning. Unknown fields, managed or non-colon emoji state, absent rename targets, exact-name collisions, and exhausted capacity must fail closed.
Keep create, rename, and delete behind the independent change toggle, process-keyed planning, signed interactive confirmation, write-aware host approval, final fresh-plan match, atomic one-shot operation-key reservation, pending content-free activity, one non-retried mutation, and exact metadata or complete-inventory absence readback. Require explicit global-impact acknowledgement for delete because the emoji may be referenced through every application installation. Do not add an audit-reason field because Discord does not document one for these endpoints. An already-current rename or already-absent delete must remain an operation-record-free no-op with no confirmation, reservation, activity entry, or mutation.
Creation must accept only one bounded canonical owned JPEG, PNG, GIF, WebP, or AVIF file under a dedicated application-emoji root. Never accept a remote URL, Discord CDN reference, data URL, base64 payload, arbitrary byte field, stream, directory, multiple files, or runtime-configurable Discord origin. Reject path escapes, symlinks, hardlinks, foreign ownership, unstable reads, unsupported formats, and files above Discord's byte limit before reservation. Upload only the reviewed byte snapshot bound into the fresh plan. Never claim stored-byte verification because Discord exposes only emoji metadata after creation.
Serialize changes per application inside one process as defense in depth. The production facade must also acquire one durable exact application emoji-collection claim so connector processes sharing the activity-state root exclude every overlapping application-wide change, regardless of emoji ID or operation key. A known pre-response Discord client rejection may be failed. Transport ambiguity, rate limiting, server failure, malformed mutation evidence, failure after mutation, readback failure, or receipt-finalization failure is uncertain and potentially completed. Retain the application claim after uncertainty and block queued same-application work. Never retry, compensate, restore, or roll back automatically.
Never persist emoji names, local paths, file metadata, image bytes, content digests, uploader data, raw operation keys, raw payloads, or private evidence. Activity and operation records may contain only exact application and emoji IDs, action, plan digest, operation-key hash, timestamps, fixed verification and outcome values, activity ID, and sanitized error category.
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.