Security Model
MarrowStack blocks make specific, testable security guarantees. This page documents what those guarantees are, what is explicitly outside their scope, and what you must implement on your side.
What the blocks guarantee
Passwords are never stored in plaintext
The Auth block hashes passwords with bcrypt before writing to the database. The plaintext value is never logged, returned, or stored. The work factor defaults to 12 rounds (configurable up, not down below 10).
Cryptographic verification is server-side only
For SIWS (Solana Auth), Ed25519 signature verification runs on the server using tweetnacl. The block never trusts a client claim that verification succeeded. For payments, on-chain verification runs via your RPC before any value-delivery path is reached.
Nonces and tokens are single-use
Auth nonces are consumed atomically with a conditional UPDATE (WHERE consumed_at IS NULL). A second verify attempt with the same nonce returns 409. Invite tokens work identically.
Idempotency on payments
The payment signature is stored in an idempotency_key UNIQUE column. A duplicate verify attempt for the same on-chain transaction returns 409 ALREADY_CREDITED rather than double-crediting.
Row-Level Security on all tables
Every SQL migration enables RLS and sets policies. Service role operations (server-side) bypass RLS intentionally. Client-side Supabase access (if you add it) is constrained by RLS policies.
Domain binding in SIWS
The Solana Auth block checks the domain field in every SIWS message against SOLANA_AUTH_DOMAIN. A mismatch rejects the request. This prevents cross-origin replay attacks.
Brute-force lockout
The Auth block tracks failed login attempts per IP. After MAX_LOGIN_ATTEMPTS failures within LOCKOUT_WINDOW_MINUTES, that IP is blocked until the window expires.
Verify before delivering value
This is the most important rule for Solana payments.
The usePaymentStatus hook fires onConfirmed only after the status API returns confirmed, which itself only fires after server-side verifyPayment() passes all 6 checks. Despite this, your product delivery logic must independently call verifyPayment()or check the DB status before writing the order. Defense in depth: if the client call is intercepted or replayed, your server is the last line of defense.
What is your responsibility
- HTTPS everywhere. The blocks do not enforce transport security — your infrastructure must serve over TLS. SIWS signatures over plain HTTP are trivially interceptable.
- Secret management. Never expose
SUPABASE_SERVICE_ROLE_KEY,NEXTAUTH_SECRET, orSMTP_PASSto the client. Use Next.js server-only env vars (noNEXT_PUBLIC_prefix) for all secrets. - RPC reliability. For Solana payments in production, use a private RPC (Helius, QuickNode, Alchemy). Public devnet and mainnet RPCs have aggressive rate limits that will cause confirmation polling to fail under load.
- USDC mint address verification. Before going to mainnet, verify the USDC mint addresses against Circle's official documentation. The block ships with the correct addresses at time of writing, but you must confirm them for your deployment.
- Nonce TTL lower bound. Do not set
SOLANA_AUTH_NONCE_TTL_SECONDSbelow 60. Very short windows cause legitimate users to fail the timestamp check on slow connections. - Admin route authorization. The Admin block's
requireAdmin()must be called at the top of every admin route handler and server component. The block does not apply middleware-level protection. - Dependency updates. You own the block file. Monitor
@solana/web3.js,tweetnacl,next-auth, andbcryptjsfor security advisories.
Out of scope
The following are not covered by any block and must be implemented at the infrastructure or application layer:
- DDoS protection (use Cloudflare or your CDN's WAF)
- Rate limiting at the network edge (beyond the per-IP lockout in the Auth block)
- Content Security Policy headers
- CORS policy enforcement
- Database backups and point-in-time recovery
- Solana validator-level MEV resistance (private RPC helps at the RPC layer)
Reporting issues
The two Solana blocks are MIT-licensed and open source. Report security issues by email to security@marrowstack.dev. For the web2 blocks, use the same address. Please do not file public GitHub issues for security vulnerabilities.