Access control — ZevID¶
Who can access what production data, with which authentication, and where each access is audited.
Access tiers¶
Engineering — production data¶
- Who: ZevID engineering team.
- How: through the admin panel (which audits to
admin_audit_logs) and through deploys (audited via Git history). Engineering does NOT hold direct read access to production secrets — that's Ops-only (seesecurity.md→ Key + secret management).
Operations — production secrets + host¶
- Who: Ops team.
- What they can see / change: production secrets on the VPS host (
FIELD_ENCRYPTION_KEY,PHONE_HASH_PEPPER,ADMIN_JWT_SECRET, JWT RS256 keys, vendor API tokens). Host-level OS administration. Neon database administration. - Authentication: SSH key access to the VPS.
Operations / Admin staff — admin panel¶
- Who: staff with
admin_usersrows. - Authentication: admin login at
admin.zevop.com— email + password + admin MFA (TOTP enforced for privileged actions). - What they can see: user profiles, sessions, login events, KYC outcomes, ZPIP grants, recent ZPIP token activity, Zev Credit state, referrals, invites, OAuth client configs, service keys, admin audit logs.
- What they can change: ban / unban accounts, revoke sessions, disable MFA (with re-auth), reset geo-fencing, reset IP whitelist, force password reset, revoke app passwords. Create / revoke service keys (super-admin only). Edit OAuth clients (super-admin only).
- Audit trail: every action lands in
admin_audit_logs(admin_id, action, target_type, target_id, details, ip_address, created_at).
ZevID super-admins¶
- Who: senior engineers with
admin_users.role = 'super_admin'. - Authentication: same as admin staff + sensitive-action MFA re-prompt on creating / revoking service keys, editing OAuth clients, and accessing the cross-product audit views.
Automated jobs / cron¶
- Cleanup cron (
cleanup.service.ts) — daily 3am UTC, in the NestJS process. Touchesotps,authorization_codes,sessions,login_events. Logged via Sentry Cron Monitor + Better Stack heartbeat. - ZPIP cron (
zpip-cron.service.ts) — same process; sweeps expired ZPIP consent requests.
Sensitive-action MFA re-prompts¶
The following actions require a fresh MFA challenge even when the user is already signed in:
- Change password.
- Disable TOTP.
- Regenerate recovery codes.
- Toggle "Require 2FA on product logins" (
mfaEnforceOnOauth). - Issuing or revoking a service key.
- Editing an OAuth client.
- Banning / unbanning an account.
Joiner / leaver¶
New admin access is created by a super-admin assigning the appropriate product_permissions to a new admin_users row. On departure, is_active=false is set on the row, any service keys issued by the leaver are revoked, and shared secrets the leaver had access to are rotated by Ops.