AttendiBotAttendiBot

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:

  1. Finalizes the session (duration, user, channel, timestamps)
  2. Serializes the payload to canonical JSON
  3. Computes a SHA-256 hash of the canonical payload
  4. Signs the canonical bytes with the server's Ed25519 private key
  5. Stores the session UUID, payload hash, and signature

Period snapshots

When a leaderboard period resets, AttendiBot:

  1. Builds a snapshot payload (period metadata + all leaderboard entries)
  2. Signs the snapshot with the same Ed25519 key
  3. 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 → SigningRotate 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:

  1. Go to attendibot.com/#verifier
  2. Choose Session UUID or Period lookup
  3. 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).

  1. Go to attendibot.com/#verifier
  2. Choose Offline receipt
  3. 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).

  1. Verify the receipt offline (above)
  2. On the verifier, choose Transparency proof to confirm the record exists in the log
  3. 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:true

Verify period archives (public)

Use the marketing site verifier (Period lookup, Offline receipt, or Transparency proof tabs).

Security best practices

  1. Limit Manage Server access — only trusted admins can generate or rotate keys
  2. Share public keys openly — verification requires the public key, not the private key
  3. Rotate, don't re-generate — use Rotate keys after initial setup; old signatures remain verifiable via per-record key references
  4. Confirm before rotating — rotation changes the active public key for all new sessions; notify external verifiers to fetch the updated key
  5. Rotate on compromise immediately — treat suspected key exposure as an incident

What happens when signing fails

StateBehavior
No keys configuredSessions not recorded; admin prompted to generate keys
Keys not loadedActive sessions tracked in memory but dropped on leave
Invalid signature on verifyVerifier 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.

Edit on GitHub

On this page