Security Model

How NETWORKCOIN.ID protects your users and your applications.

OAuth 2.1 Compliance

  • PKCE Required — All authorization requests must include a code_challenge (S256). Prevents authorization code interception.
  • No Implicit Flow — Only authorization code flow. Tokens never appear in URLs.
  • State Parameter — Recommended to prevent CSRF attacks.

Token Security

TokenFormatLifetimeNotes
Access TokenRS256 JWT1 hourVerifiable without calling our servers
ID TokenRS256 JWT + PQ sig1 hourContains identity claims filtered by scope
Refresh TokenOpaque (SHA-256 hashed)30 daysRotated on every use

Refresh Token Rotation

Every time a refresh token is used, a new one is issued and the old one is revoked. If a revoked token is ever reused (indicating theft), all tokens for that client+user are immediately revoked.

Post-Quantum Hybrid Signing

ID tokens are dual-signed:

  • RS256 — Classical RSA signature. Standard OIDC clients verify this.
  • EdDSA (Ed25519) — Post-quantum bridge signature in pq_sig claim. PQ-aware clients can verify both.

When Node.js/WebCrypto adds ML-DSA (CRYSTALS-Dilithium) support, the Ed25519 bridge will be swapped to ML-DSA-65 with no protocol changes.

Signing Key Management

  • RS256 (RSA 2048-bit) + Ed25519 keypairs
  • Published at /.well-known/jwks.json
  • Rotatable by superadmins via the security dashboard
  • Old keys remain active for 24 hours after rotation (grace period), then auto-deactivate

Rate Limiting

Multi-tier rate limiting per IP AND per account:

EndpointBurstSustainedLockout
Login (per IP)5/min15/hr1 min → 15 min
Login (per email)5/min15/hrAccount locked 15 min
Registration3/5min10/hr5 min → 30 min
SIWE (per wallet)5/5min10/hrWallet locked 5 min → 1 hr
Token Exchange60/min600/hrWindow
Password Reset3/5min5/hr10 min → 1 hr
Payment Charge10/min100/hrOAuth token required + payments scope

Wallet Authentication (SIWE)

  • Non-custodial — We never store or access private keys
  • EIP-4361 (SIWE) — Standard Sign-In with Ethereum messages
  • Nonce-based — Challenges expire after 5 minutes, single-use
  • Server-side verification — Signatures verified via viem.verifyMessage()

Session Security

  • HS256-signed JWTs in httpOnly, Secure, SameSite=Lax cookies
  • 24-hour expiration
  • Every session tracked in database with IP, device, user agent
  • Users can view and revoke sessions from their dashboard
  • Password reset automatically revokes all sessions

Audit Logging

Every security-relevant action is logged with event type, action, user ID, IP address, timestamp, and contextual details:

  • Login attempts (success and failure)
  • Registration, email verification
  • Password changes and resets
  • OAuth consent grants and revocations
  • Token issuance, refresh, and revocation
  • Session creation and revocation
  • Signing key rotations
  • Superadmin actions (suspend, promote, demote)
  • Payment method additions and removals
  • Payment charges (success and failure)

Payment Security

  • PCI compliant via Stripe — Card numbers never touch our servers. Stripe Elements sends them directly to Stripe.
  • We only store references — Stripe customer ID, payment method ID, last 4 digits, and expiry for display.
  • Scope-gated — Apps can only charge if the user explicitly granted the payments scope during OAuth consent.
  • OAuth token required — The charge API validates the access token and checks for the payments scope before processing.
  • Minimum 1 card — Users cannot remove their last payment method (same as Apple).