Hall of Progress

How Venom is built.

HOP documents the systems behind Venom, what they do, why they exist, and how the project has changed while being built. It is intended to be technical enough to explain the architecture without turning into an API reference.

VENOM / HOP WEB / 01
SECTION 01

Web

The web platform is more than a landing page. It is the account, community, administration, authentication, and licensing control plane around Venom.

Forum

The forum gives Venom a first-party place for announcements and community discussion instead of requiring every update to live only inside Discord. Posts can carry markdown, embedded images, likes, comments, author identity, and Venom roles.

Purpose: keep important project information attached to a Venom account and available even when a user is not actively inside the Discord server.
Administration: posting is currently controlled by admins, while comment permissions can be configured per post.

Dashboard

The dashboard is the authenticated control centre for a Venom account. It combines profile identity, Discord linking, license state, account security, password controls, usage information, forum access, and admin entry points when the account has the required role.

Purpose: provide one predictable place where users can see the state of their account rather than spreading sensitive controls across unrelated pages.

Pepper

A password pepper is server-side secret material that is combined with the password before the expensive password derivation step. Unlike a salt, the pepper is not stored beside each user's password record.

Venom uses a server-side password pepper before PBKDF2. This means a database-only compromise does not give an attacker every input required to test password guesses against the stored verifier.

Why: database records and application secrets have different compromise boundaries. Keeping part of the password derivation secret outside D1 adds another boundary an attacker has to cross.
conceptual flow
password = "user supplied password"
peppered = HMAC_SHA256(password, PASSWORD_PEPPER)
verifier = PBKDF2(peppered, accountSalt, iterations)

// PASSWORD_PEPPER stays in server secrets

Salt

Every password account gets its own random salt. The salt does not need to be secret. Its job is to make identical passwords produce different stored password verifiers.

Venom currently generates a random 32-byte salt per password account before running password derivation. The salt is stored with the resulting password verifier so the same derivation can be performed during login.

Why: without unique salts, two users who choose the same password can end up with matching password hashes, and precomputed cracking tables become much more useful.
two users, same password
User A
password = samePassword
salt = random_A
result = 7d8a...

User B
password = samePassword
salt = random_B
result = b921...

Hashing

Hashing is used when Venom needs to compare a value without needing to recover the original value later. Different jobs use different constructions rather than treating one hash function as a universal solution.

Authentication session tokens are reduced to SHA-512 hashes before storage, meaning D1 does not need the usable bearer token. Lookup identifiers such as emails and Discord IDs use keyed HMAC lookups so common values cannot simply be guessed and hashed offline.

Why: if the application only has to answer "does this value match?", storing a recoverable plaintext copy increases exposure for no benefit.
session storage
clientToken = secureRandom(48)
storedValue = SHA512(clientToken)

request Authorization:
Bearer clientToken

server:
SHA512(clientToken) == storedValue

Encryption

Encryption is used when Venom genuinely needs to recover a value again. Discord IDs, Discord names, avatars, display/profile information, and other sensitive recoverable values are encrypted before storage using authenticated encryption.

The current profile encryption path derives an AES-GCM key from the profile secret and uses a random 12-byte IV for each encrypted value. The IV is stored alongside the ciphertext because it is required for decryption but does not itself need to be secret.

Why: hashing would prevent Venom from ever using the original Discord ID or avatar again, while plaintext storage exposes more information than necessary. Encryption fits data that needs to be recoverable.
encrypted profile value
key = SHA256(PROFILE_SECRET)
iv = secureRandom(12)
ciphertext = AES_GCM_ENCRYPT(value, key, iv)

stored =
base64url(iv + ciphertext)
Important distinction: passwords are not encrypted. Passwords are one-way derived. Encryption is reserved for information Venom must be able to recover.