Skip to content

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 (see security.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_users rows.
  • 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. Touches otps, 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.