Security
BlockID is built to reduce identity-theft risk, reduce the impact of a breach, minimize unnecessary storage of sensitive identity data, and make tampering easier to detect. This page explains the mechanisms and gives you a hardening checklist for production.
Private, tamper-evident ledger
Every credential issuance, revocation, and key event is written to a private MySQL ledger. Each record includes the hash of the previous record, forming a hash chain. Altering any past record would change its hash and break every link after it — which is exactly what Verify Ledger Integrity detects by re-walking the chain. This design makes tampering easy to detect after the fact; it is a private database structure, not a public blockchain or cryptocurrency.
Digital signatures
Each issuing identity is a DID (did:blockid:{uuid}) with an RSA-2048 keypair. When a credential is issued, BlockID builds a canonical form, computes its SHA-256 hash, and signs that hash with the private key using RSA-SHA256. Verifiers recompute the hash and check the signature against the issuer's public key — so a credential's authenticity and integrity can be checked without trusting the holder.
Revocation
A dedicated revocation registry lets issuers withdraw trust before a credential's natural expiry. Once revoked, verification returns REVOKED and a ledger entry records the event. Revocation is permanent.
Secure sessions
Authentication uses server-side sessions. Sign-out is performed as a CSRF-protected POST to /logout.php. Repeated failed logins can trigger a temporary lockout to slow brute-force attempts. Always serve the app over HTTPS so session cookies are protected in transit.
RBAC & organization isolation
Five roles (Super Admin, Org Admin, Issuer, Verifier, End User) gate every action. On top of roles, strict organization scoping ensures a user can only touch data inside their own organization — enforced on the server for every request, which defends against cross-tenant (IDOR) access even if a record ID is guessed.
Prepared statements
All database access goes through a PDO wrapper using prepared statements with bound parameters. User input is never concatenated into SQL, which prevents SQL injection.
CSRF protection
State-changing forms and actions (including sign-out, issuance, and revocation) require a per-session CSRF token. A missing or stale token is rejected with 403. If a user hits this, reloading the page issues a fresh token.
Audit trails
Sensitive actions — logins, user and token changes, issuance, revocation — are recorded in an audit log that admins can review and filter. Combined with the ledger, this gives both a human-readable history and a cryptographically chained one.
API token security
- Tokens are stored only as SHA-256 hashes and shown exactly once.
- Each token is scoped to one organization and limited to specific scopes.
- Tokens can expire and be revoked instantly.
- Requests are rate-limited to 120/min and logged.
Security headers & locked-down directories
In production, BlockID should send a strict set of response headers, and sensitive directories must be denied over HTTP.
| Header | Purpose |
|---|---|
Strict-Transport-Security | Force HTTPS for future visits. |
Content-Security-Policy | Restrict what can load; mitigates XSS. |
X-Content-Type-Options: nosniff | Stop MIME sniffing. |
X-Frame-Options / frame-ancestors | Prevent clickjacking. |
Referrer-Policy | Limit referrer leakage. |
/config, /core, and /storage are denied over HTTP — requesting them returns 403. This keeps configuration, core code, and logs off the public web.
Error handling without leaks
In production, raw errors and stack traces are never shown to users. Database problems are converted to friendly pages (for example /errors/database.html and /errors/config-missing.html), while the precise cause is written to storage/logs/php-error.log for operators. See Troubleshooting.
Production hardening checklist
Delete
/installRemove the installer immediately after setup.
Enforce HTTPS + HSTS
Serve everything over TLS and enable HSTS.
Set security headers
Add CSP, nosniff, frame protection, and Referrer-Policy.
Deny sensitive directories
Confirm
/config,/core,/storagereturn 403.Turn off
display_errorsErrors go to
storage/logs/php-error.log, not the screen.Use least-privilege DB & tokens
Scope the DB user to one database; scope API tokens narrowly with expiries.
Rotate & revoke
Rotate API tokens on a schedule; revoke promptly on exposure.
Verify the ledger routinely
Run Verify Ledger Integrity on a schedule and after maintenance.
Back up the database
Regular, tested backups — the ledger and credentials live there.
Review audit logs
Watch for unexpected logins, token use, and revocations.
Deployment →
Where to set headers, permissions, and HTTPS.
Testing →
Verify your hardening actually holds.