This policy operates alongside Authentication (how we verify identity). This page covers authorization — who gets access to what, for how long, and how we verify it stays correct.
Principles
Least privilege
Every identity gets the minimum permissions needed to perform its role. Permissions are additive and opt-in, not stripped-down from a broad default.
Role-based
Permissions attach to roles, not individuals. Individuals inherit permissions via role assignment.
Separation of duties
Critical operations require two independent actors (e.g. deploy + approval; policy change + security officer sign-off).
Periodic review
Access isn’t fire-and-forget. Every access grant is reviewed on a defined cadence; unused grants are revoked.
Just-in-time for privileged access
Privileged operations (prod database read, secret rotation) use time-limited elevation rather than persistent grants.
Audit by default
Every grant, revocation, and use of privileged access is audit-logged for 7 years.
Identity types
| Identity type | Examples | How it authenticates |
|---|---|---|
| Customer user | Billing staff, provider, practice admin | Password + 2FA (TOTP/passkey), OAuth, or SAML SSO |
| Denialbase workforce | Employee, contractor | SSO via Google Workspace + enforced 2FA |
| Service account (runtime) | Cloud Run backend, worker VM | GCP IAM binding + Workload Identity (no long-lived keys) |
| CI/CD identity | GitHub Actions deploy workflows | Workload Identity Federation (short-lived OIDC → GCP token exchange) |
| API token | Server-to-server integrations | Scoped, revocable, time-bound token (see Authentication — API tokens) |
Customer-side access control
Roles
Roles
Five roles (see Admins — team management):
| Role | PHI access |
|---|---|
user | Own work, within assigned queues |
analyst | Aggregated/anonymized only |
support | Read-only, scoped |
admin | Full within org, no delete |
(Denialbase internal) super_admin | Full platform, heavily audited |
Policy enforcement
Policy enforcement
Every API action is authorized by a Pundit policy (48 policy files as of April 2026).
ApplicationController enforces after_action :verify_authorized globally — any action that doesn’t authorize or skip raises.Tenancy isolation
Tenancy isolation
Every PHI-bearing row carries an
organization_id. Pundit policies scope queries to the caller’s organization by default. Cross-tenant access requires an explicit super-admin policy and is audit-logged.Session controls
Session controls
30-minute idle timeout; 24-hour maximum session. Configurable per org.
Workforce-side access control
Standard access
Granted on hire based on role. Reviewed quarterly.| System | Role-based defaults |
|---|---|
| GitHub | Developers: write to denialbase repo; others: none |
| Google Workspace | Email, Drive, Calendar for all |
| GCP (staging) | Developers: view; operations: write |
| GCP (production) | No direct access by default; just-in-time only |
| 1Password | Shared vaults by role |
| Sentry | Engineering: access to error events |
| Customer admin UI | Support + ops: read-only, scoped, ticketed |
Privileged access
Production data access is just-in-time:Request
Engineer or operator opens a break-glass request with: reason, ticket link, scope (what data), duration (≤ 4 hours by default).
Segregation of duties (A.5.3)
| Activity | Separated |
|---|---|
| Deploy code to prod | CI/CD pipeline (not any individual engineer) |
| Approve a PR | Author ≠ reviewer |
| Change an Annex A control | Security Officer + one other executive |
| Rotate encryption keys | CTO proposes + Security Officer approves + independent reviewer verifies |
| Modify audit log retention | Security Officer + CTO; any change audit-logged in a higher-tier log |
Service account access control
- Minimum privilege per service account — Cloud Run runtime SA has access only to the secrets and resources it needs at runtime.
- No long-lived keys — Workload Identity Federation for CI/CD, Workload Identity (in-cluster) for service-to-service.
- Annual review of service account IAM bindings as part of internal audit.
- Automatic revocation of unused service accounts (90-day idle threshold).
Access review (A.5.18)
Quarterly access reviews are a top audit focus. We don’t skip them.
| Review type | Frequency | Who performs | Artifact |
|---|---|---|---|
| Standard user access | Quarterly | Engineering manager (per report) | Signed review record |
| Privileged access | Monthly | Security Officer | Review record |
| Service account IAM | Quarterly | CTO | Review record |
| Customer-admin UI grants (support) | Quarterly | Head of Support | Review record |
| Third-party tool grants (Sentry, Slack, GitHub orgs) | Quarterly | Security Officer | Review record |
| Post-offboarding | Within 1 business day of termination | Security Officer | Confirmation logged in HR record |
| Post-role-change | Within 1 business day of effective date | Security Officer | Confirmation logged in HR record |
Password and credential hygiene
- Passwords must meet the complexity rules defined in the AUP.
- 1Password is provided and required — no reuse, no local storage in plaintext.
- MFA required on every account with production-adjacent access.
- No shared credentials for any system (exceptions documented).
Emergency / break-glass access
For production incidents:- A pre-approved break-glass role exists that grants broad access for a 4-hour window.
- Granted by the Security Officer (or CTO if SO unreachable).
- Use is written up within 24 hours in the incident post-mortem.
- Reviewed at the next management review.
Failure to comply
- First-time minor violations: retraining.
- Repeat or material violations: discipline per AUP enforcement.
- Willful breaches involving PHI: termination + referral as required by law.
Related
- Authentication — the “how we verify identity” companion
- HR security — onboarding/offboarding tied to access changes
- Audit logging — the record of who did what, when