Signing & Verification
Ed25519 signing, keys, and public verification.
AttendiBot's core differentiator is cryptographically verifiable voice attendance. Every completed session and archived period snapshot is signed with Ed25519, so anyone can prove records were not tampered with.
What gets signed
Voice sessions
When a member leaves a tracked voice channel, AttendiBot:
- Finalizes the session (duration, user, channel, timestamps)
- Serializes the payload to canonical JSON
- Computes a SHA-256 hash of the canonical payload
- Signs the canonical bytes with the server's Ed25519 private key
- Stores the session UUID, payload hash, and signature
Period snapshots
When a leaderboard period resets, AttendiBot:
- Builds a snapshot payload (period metadata + all leaderboard entries)
- Signs the snapshot with the same Ed25519 key
- Archives the signed snapshot for later verification
Key lifecycle
1. Generate keys (once per server)
Generate keys from the dashboard:
- Dashboard → Signing → Generate keys
Or in Discord:
/admin generate-keys
The private key is encrypted at rest with platform-managed keys. Only the encrypted blob and public key are stored. Signing is active immediately and reloads automatically after bot redeploys.
Important: Initial generation is allowed only once per server. If keys already exist, the dashboard shows Rotate keys instead.
2. Rotate keys
Use rotation when you suspect key compromise, after admin offboarding, or on a periodic schedule (e.g. every 90–180 days for high-audit communities).
- Dashboard → Signing → Rotate keys (confirmation required)
- Or
/admin rotate-keys
Rotation creates a new active key for future sessions. Older sessions and period snapshots remain verifiable using the public key tied to each record.
Anyone verifying attendance externally must fetch the updated public key after rotation.
3. Share the public key
Anyone verifying sessions needs the server's public key:
- Dashboard → Signing → Public key
- Or
/admin public-key
The public key is safe to share publicly — it cannot sign new records.
Verification workflow
AttendiBot supports three verification modes. See Independent Verification for full offline and transparency log details.
Quick lookup (UUID)
Anyone can verify a session without logging in:
- Go to attendibot.com/#verifier
- Choose Session UUID or Period lookup
- AttendiBot fetches the record and verifies the Ed25519 signature server-side
This mode requires trusting AttendiBot's database.
Offline receipt verification
Pro signed exports and session.completed webhooks include a self-contained receipt (signed_payload, signature, payload_hash, public_key).
- Go to attendibot.com/#verifier
- Choose Offline receipt
- Paste or upload receipt JSON — verification runs in your browser with no API call
Or use the CLI: attendibot-verify session --receipt receipt.json
Transparency log (inclusion proofs)
Each signed session is appended to a per-guild RFC 6962-style Merkle log. Pro receipts include log_index, inclusion_proof, and sth (signed tree head).
- Verify the receipt offline (above)
- On the verifier, choose Transparency proof to confirm the record exists in the log
- Public keys:
GET /verify/keys/{guild_id}or/.well-known/attendibot/{guild_id}.json
Admins backfill historical records with /admin backfill-transparency-log (dry-run first).
Verify in Discord
Admins can verify sessions and period archives directly:
/admin verify-session session_id:550e8400-e29b-41d4-a716-446655440000
/admin verify-period period_index:1
/admin backfill-transparency-log dry_run:trueVerify period archives (public)
Use the marketing site verifier (Period lookup, Offline receipt, or Transparency proof tabs).
Security best practices
- Limit Manage Server access — only trusted admins can generate or rotate keys
- Share public keys openly — verification requires the public key, not the private key
- Rotate, don't re-generate — use Rotate keys after initial setup; old signatures remain verifiable via per-record key references
- Confirm before rotating — rotation changes the active public key for all new sessions; notify external verifiers to fetch the updated key
- Rotate on compromise immediately — treat suspected key exposure as an incident
What happens when signing fails
| State | Behavior |
|---|---|
| No keys configured | Sessions not recorded; admin prompted to generate keys |
| Keys not loaded | Active sessions tracked in memory but dropped on leave |
| Invalid signature on verify | Verifier returns invalid |
If signing shows as not loaded after a redeploy, contact support. If archived periods show invalid signatures, use Repair period snapshots in the dashboard (or /admin repair-periods) after a dry run. See Troubleshooting.
Related docs
- Getting Started — initial key setup
- Commands — signing admin commands
- FAQ — common signing questions