Purpose
This policy establishes requirements for controlling access to Maelstrom AI’s information systems, ensuring that only authorised individuals can access resources appropriate to their role.
Scope
Applies to all systems, applications, and data within the ISMS scope, including:
- GitHub repositories and workflows
- Cloudflare Workers, KV, and Durable Objects
- Developer workstations
- Cloud provider consoles
- Communication platforms
Principles
Least Privilege: Users granted minimum access necessary for their role Need-to-Know: Access based on job function requirements Segregation of Duties: Critical operations require multiple people (where feasible) Zero Trust: Verify explicitly, assume breach, least privileged access
Authentication Requirements
Multi-Factor Authentication (MFA)
Required for all access to:
- GitHub (code repository, CI/CD)
- Cloudflare (production infrastructure)
- Email accounts
- Password managers
- Any system with access to production secrets
MFA Methods (in order of preference):
- Hardware security keys (YubiKey) - Planned for critical accounts
- Authenticator apps (Authy, Google Authenticator)
- SMS (least preferred, but acceptable if no alternative)
Enforcement: MFA cannot be disabled. Account access blocked until enabled.
Password Requirements
All passwords must:
- Be stored in approved password manager (1Password, Bitwarden)
- Be unique (no reuse across services)
- Be strong (password manager generated recommended)
- Never be shared between individuals
- Never be stored in plain text
- Never be included in source code or logs
Password Managers:
- Required for all team members
- Company-provided licences available
- Master password must be strong and unique
- MFA enabled on password manager itself
Authorisation Model
GitHub Access
Repository Access:
- Public repositories: Open source, world-readable
- Private repositories (if any): Team members only, role-based
Branch Protection (main branch):
- ✅ Pull request with mandatory self-review and passing CI status checks before merge. Two-person approval is not feasible for a sole operator (accepted limitation).
- ✅ Dismiss stale reviews when new commits pushed
- ✅ Require review from CODEOWNERS
- ✅ Require status checks to pass
- ✅ Require signed commits (GPG)
- ✅ Include administrators (no bypass)
Administrative Access:
- Limited to the ISMS Owner (sole operator)
- Required for: Repository settings, security settings, Actions secrets
- Audited via GitHub audit log
Personal Access Tokens:
- Scoped minimally (only required permissions)
- Expiration set (max 90 days, shorter preferred)
- Stored in password manager
- Revoked immediately on compromise or departure
Cloudflare Access
Production Environment:
- Admin access: Security Lead only (sole operator)
- Worker deployment: Via CI/CD (automated) or emergency manual by Security Lead
- KV access: Only via Workers (no direct access)
- Analytics: Read-only access via Cloudflare dashboard (Security Lead)
API Tokens:
- Scoped to specific zones/accounts
- Minimal permissions (e.g., “Workers:Edit” only)
- Stored in GitHub Secrets (for CI/CD) or password manager
- Rotation: Annually or on compromise
- Audit log reviewed for suspicious activity
Secrets Management:
- Production secrets: Cloudflare Workers Secrets (encrypted at rest)
- Never in source code or wrangler.toml
- Access only via
wrangler secret putcommand - Secrets automatically available to Workers at runtime
Developer Workstation Access
Operating System:
- Strong password or biometric unlock
- Full disk encryption mandatory (FileVault, BitLocker)
- Automatic screen lock (5-minute timeout)
- OS security updates required within 7 days
Privileged Access:
- sudo/admin access: Individual workstations only
- No shared admin accounts
- Principle of least privilege for sudo commands
Access Provisioning
New Team Member Onboarding
Access granted upon:
- Completion of background check
- Signing of employment agreement and NDA
- Completion of security awareness training
- Acknowledgment of acceptable use policy
Standard Access Package:
- GitHub: Member access to team organisation
- Cloudflare: Role-based access (developer: limited, admin: selective)
- Communication tools (Signal, email)
- Password manager licence
- Documentation access
Timeline: Access provisioned within 24 hours of completion of requirements
Access Changes
Role Change:
- Access adjusted within 1 business day
- Old privileges removed
- New privileges granted per new role
- Documented in access change log
Temporary Elevation:
- Approved by ISMS Owner
- Time-limited (clearly specified duration)
- Purpose documented
- Revoked automatically at expiration
Access Reviews
Quarterly Review
Conducted by: Security Lead Reviewed by: ISMS Owner
Process:
- Export GitHub organisation members
- Export Cloudflare account access lists
- Verify each account matches current team roster
- Check for unused accounts (>90 days inactive)
- Verify privileged access still required
- Remove or adjust as needed
- Document findings
Timeline: Within first week of each quarter
Event-Triggered Reviews
Reviews conducted immediately upon:
- Team member departure
- Role change
- Security incident involving access
- Suspected compromise
Access Revocation
Termination or Departure
Immediate Actions (within 1 hour of departure notice):
- Disable GitHub account or remove from organisation
- Revoke Cloudflare access
- Remove from communication channels (Signal, email lists)
- Revoke API tokens and rotate shared secrets if necessary
- Collect company property (if applicable)
Verification (within 24 hours):
- Confirm all access revoked via access review
- Check audit logs for any post-termination activity
- Verify no active sessions remain
Documented via: Offboarding checklist, access audit log
API and Service Account Authentication
API Authentication Methods
Verifier API (expert integrations):
- Client identification via X-API-Key header (Argon2id-hashed, prefix-indexed)
- HMAC-SHA256 request signing with per-client secrets (AES-256-GCM envelope-encrypted at rest)
- Timestamp validation (max 60s ahead / max 5min behind)
- Nonce-based replay protection via Durable Objects
- Origin validation (CORS + origin allowlist)
- Rate limiting per API key
Verifier Hosted Mode (simple website integrations):
- Public key authentication (
pk_live_/pk_test_prefixed keys) - Origin-based validation for browser requests
- HMAC-SHA256 signed session token issuance after successful verification
Issuer API:
- Officer authentication: YubiKey HMAC-SHA1 challenge-response (hardware constraint)
- Client authentication: HMAC-SHA256 with client secret
- Ed25519 attestation verification for trust-based issuance flow
- Session-based authentication after initial challenge
- Replay protection via nonce cache
Implementation: See /trust/security/cryptography-policy for HMAC details
Service Account Management
Cloudflare API Tokens (CI/CD):
- Stored in GitHub Secrets (encrypted)
- Scoped minimally (Workers:Edit for deployment)
- Used only by GitHub Actions (automated)
- Rotation: Annually or on suspected compromise
GitHub Personal Access Tokens (if used):
- Scoped to specific repos/actions
- Expiration: 90 days maximum
- Stored in password manager or CI/CD secrets
- Never committed to code
Remote Access
Context: All team members work remotely (no office)
Requirements:
- MFA for all cloud service access (GitHub, Cloudflare)
- VPN not required (zero-trust, cloud-native architecture)
- Public WiFi: Acceptable with HTTPS (all communications encrypted)
- Home network security guidance provided
See also: Acceptable Use Policy for remote work requirements
Monitoring and Auditing
Audit Logging
Logged Events:
- Authentication attempts (success and failure)
- Privileged actions (GitHub admin, Cloudflare admin)
- Access to signing keys (KV namespace access)
- API authentication failures
- Account changes (creation, deletion, permission changes)
Log Storage:
- GitHub: GitHub audit log (90-day retention)
- Cloudflare: Workers Logs (shipped to Grafana Loki) + audit logs
- Application: Cloudflare KV (90-day retention)
Log Review: Weekly review of privileged access events (planned - see SOA gap A.8.15/A.8.16)
Failed Authentication Monitoring
Thresholds:
- 5 failed attempts within 1 hour: Investigate
- 10 failed attempts within 1 hour: Potential brute force attack
- Lockout after 5 failed attempts (where supported)
Response:
- Notify account owner
- Security Lead investigation
- Potential account suspension pending investigation
Exceptions
Exception Process:
- Written justification submitted to ISMS Owner
- Risk assessment conducted
- Compensating controls identified
- Time limit specified
- Documented in exception log
- Reviewed quarterly
No exceptions permitted for:
- MFA requirement for production access
- Access revocation on termination
- Audit logging of privileged access
Segregation of Duties
Context and Constraints
ISO 27001 Requirement: A.5.3 requires conflicting duties and areas of responsibility to be segregated to reduce opportunities for unauthorised modification or misuse.
Sole Operator Reality: Maelstrom AI is operated by a single person (the ISMS Owner), making full segregation of duties impractical. Traditional separation (e.g., separate development, operations, and security teams) is not feasible for a sole operator.
Auditor Note: This limitation is acknowledged and addressed through compensating controls that provide equivalent risk mitigation. This approach is acceptable under ISO 27001 for small organisations.
Current Operator Structure
As of February 2026:
Maelstrom AI has a single operator who holds all roles concurrently:
- ISMS Owner / Security Lead / Developer. ISMS ownership, final decisions on all security matters, policy approval, resource allocation, ISMS maintenance, risk assessments, incident response, access control management, cryptographic key management, security monitoring, development, code review, and testing.
Bus Factor: The sole operator is a single point of continuity. Business continuity relies on documented runbooks, access-recovery procedures, and the access-recovery documentation maintained in the ISMS. In the event the sole operator is unavailable, recovery depends on those documented procedures.
Compensating Controls
To mitigate risks from limited segregation, the following compensating controls are mandatory and enforced:
1. Mandatory Code Review (No Self-Merge)
Control: No individual can merge their own code to production branches.
Implementation:
- GitHub branch protection on
mainbranch - As a sole operator, the two-person rule cannot be enforced technically; the compensating control is mandatory self-review via pull request, CI status checks passing, and audit log review before merge
- Administrators not exempt (includes administrators rule enabled where feasible)
- CI/CD gates (automated tests, security scans) provide the primary technical barrier
Purpose: Prevents unreviewed changes from reaching production without a documented self-review record and passing automated checks
Evidence: GitHub branch protection rules, pull request history
2. Documented Authorisation for Critical Operations
Control: Operations that could cause severe damage require prior written justification and a documented record, with post-execution review.
Note: As a sole operator, true dual control (two separate people) is not achievable. The compensating control is mandatory written pre-authorisation (GitHub issue) and post-execution audit log review. This limitation is acknowledged under ISO 27001 A.5.3 for sole-operator organisations.
Critical Operations Requiring Documented Authorisation:
- Signing key generation/rotation. Written justification in GitHub issue, ISMS Owner self-approval documented, execution logged
- Production database changes. Change documented in GitHub issue before execution, rationale recorded
- Access to production secrets. Written justification, logged via wrangler audit trail
- User data deletion. Support ticket or written request, execution logged
- Security policy changes. Rationale documented, ISMS Owner sign-off recorded
- GitHub organisation ownership changes. Change documented in GitHub issue
- Cloudflare account-level changes. Change request documented before execution
Implementation:
- GitHub issue created before critical operation
- ISMS Owner (sole operator) records justification and authorisation in writing
- Execution logged in audit trail
- Post-execution confirmation recorded in same issue
Evidence: GitHub issues, audit log exports
3. Full Audit Logging
Control: All privileged actions logged and retained for 90 days; critical security event logs are retained for up to 365 days.
Logged Events:
- All GitHub administrative actions (GitHub audit log)
- Cloudflare administrative actions (Cloudflare audit log)
- Access to signing keys (application audit log)
- Deployment events (CI/CD logs)
- Secret access (wrangler secret commands logged locally)
- Account changes (user creation, deletion, permission changes)
- Authentication events (successes and failures)
Review Process:
- Weekly. Security Lead reviews privileged access logs
- Monthly. Security Lead spot-checks audit logs
- Quarterly. Full access review including log analysis
- Post-incident. Full log review
Anomaly Detection:
- Unexpected administrative actions outside business hours
- Access to signing keys without corresponding work ticket
- Multiple failed authentication attempts
- Changes to security-critical configurations
Evidence: Audit log exports, review checklists, incident reports
4. Quarterly Access Reviews
Control: Formal review of all access rights every quarter.
Process (conducted by Security Lead, reviewed by ISMS Owner):
- Export GitHub organisation member list and permissions
- Export Cloudflare account user list and roles
- Verify each account matches current team roster
- Check for inactive accounts (>90 days no activity)
- Verify privileged access still required for role
- Remove or downgrade access as needed
- Document findings and actions taken
Triggers for Immediate Review:
- Team member departure
- Role change
- Security incident
- Suspected account compromise
Timeline: First week of each quarter (Jan, Apr, Jul, Oct)
Evidence: Access review reports, before/after access lists, action logs
5. Annual Third-Party Audits
Control: External independent review of security controls and compliance.
Scope:
- ISO 27001 internal audit (Q1 2026)
- ISO 27001 certification audit when commercially justified
- Optional: Penetration testing (planned H1 2026)
- Optional: Cryptographic audit (planned H1 2026)
Purpose: Independent verification of control effectiveness, identify gaps missed by internal reviews
Evidence: Audit reports, remediation tracking, management review of findings
6. Principle of Least Privilege
Control: Access granted is minimum necessary for job function.
Implementation:
- Role-based access control (RBAC) where supported
- Scoped API tokens (minimal permissions, specific resources)
- Time-limited elevated access (revoked after task completion)
- No permanent “god mode” accounts
Examples:
- CI/CD tokens:
Workers:Editonly, scoped to specific zone - Developer GitHub tokens: Scoped to specific repos, 90-day expiration
- Cloudflare analytics access: Read-only, no write permissions
Review: Access scope reviewed during quarterly access reviews
Evidence: Access configuration exports, token scoping documentation
7. Multi-Factor Authentication (MFA) for All Privileged Access
Control: MFA required for any account with administrative or production access.
Enforcement:
- GitHub: Organisation-level MFA requirement (cannot be disabled)
- Cloudflare: MFA required for all accounts
- Password managers: MFA enabled
- Email accounts: MFA enabled
Exceptions: None permitted for privileged access
Verification: MFA status checked during quarterly access reviews
Evidence: MFA enforcement settings, user MFA status reports
8. Public Code Review (Open Source Transparency)
Control: Open source codebase provides additional scrutiny.
Benefit: Public visibility means:
- External security researchers can identify issues
- Transparent operations (any malicious changes visible)
- Community accountability
- Documented history of all changes
Limitation: Not all compensating controls are visible (internal audit logs, approval processes)
Evidence: Public GitHub repository, security researcher acknowledgments
Segregation of Duties Matrix
Note: All roles below are held by the single ISMS Owner (sole operator). This matrix documents the logical permission boundaries for each functional role and is retained for auditor reference and future personnel onboarding. Role separation is a policy intent; enforcement relies on documented self-authorisation workflows and technical controls (CI/CD gates, audit logs) rather than separate individuals.
Role-Based Permissions (what each role CAN and CANNOT do):
| Operation | Developer | Security Lead | ISMS Owner |
|---|---|---|---|
| Development | |||
| Write code | ✅ Allowed | ✅ Allowed | ✅ Allowed |
| Review code (others’) | ✅ Allowed | ✅ Allowed | ✅ Allowed |
| Merge own code without self-review | ❌ FORBIDDEN | ❌ FORBIDDEN | ❌ FORBIDDEN |
| Merge others’ code | ✅ Allowed | ✅ Allowed | ✅ Allowed |
| Production Deployment | |||
| Deploy via CI/CD | ✅ Automatic | ✅ Automatic | ✅ Automatic |
| Manual emergency deploy | ❌ No access | ✅ Allowed | ✅ Allowed |
| Rollback deployment | ❌ No access | ✅ Allowed | ✅ Allowed |
| Access Management | |||
| Provision user access | ❌ No access | ✅ Propose | ✅ Approve |
| Revoke user access | ❌ No access | ✅ Execute | ✅ Documented authorisation required |
| Modify own access | ❌ FORBIDDEN | ❌ FORBIDDEN | ❌ FORBIDDEN |
| Cryptographic Operations | |||
| Generate signing keys | ❌ No access | ✅ Generate | ❌ No access |
| Approve key rotation | ❌ No access | ❌ Cannot approve own | ✅ Required |
| Access signing keys | ❌ No access | ✅ Operational | ✅ Emergency only |
| Publish JWKS | ❌ No access | ✅ Execute | ✅ Approve |
| Production Data | |||
| Read production logs | ❌ No access | ✅ Allowed | ✅ Allowed |
| Read production data | ❌ No access | ✅ Audit only | ✅ Audit only |
| Modify production data | ❌ FORBIDDEN | ❌ FORBIDDEN | ❌ FORBIDDEN |
| Delete user data | ❌ No access | ✅ Execute | ✅ Documented authorisation required |
| Security Configuration | |||
| Propose security policy | ✅ Can suggest | ✅ Draft | ❌ N/A |
| Approve security policy | ❌ No authority | ❌ No authority | ✅ Required |
| Modify GitHub security | ❌ No access | ✅ Propose | ✅ Approve |
| Modify Cloudflare security | ❌ No access | ✅ Propose | ✅ Approve |
| Audit and Compliance | |||
| Conduct internal audit | ❌ Not assigned | ✅ Primary | ❌ Reviews only |
| Review audit findings | ❌ Informed only | ✅ Respond | ✅ Accept/Reject |
| Accept residual risk | ❌ No authority | ❌ Recommend only | ✅ Required |
Key Principles:
- ❌ No one can approve their own work (code, access changes, policy changes)
- ❌ No one can modify their own access level
- ✅ Critical operations require prior written justification and audit logging (signing keys, production data, security configs)
- ✅ All privileged actions logged (audit trail for accountability)
Authorisation Workflow for Critical Operations
Process for Critical Operations (signing key rotation example):
Note: As a sole operator, the ISMS Owner performs all roles. The control is mandatory written pre-authorisation and post-execution audit review, not a two-person gate.
- Pre-authorisation (ISMS Owner):
- Creates GitHub issue: “Q1 2026 Signing Key Rotation”
- Documents justification (scheduled rotation, suspected compromise, etc.)
- Records self-authorisation and proposed timeline in the issue
- Execution (ISMS Owner):
- Executes key generation per the documented runbook
- Logs execution details in the GitHub issue
- Records completion in audit trail
- Verification:
- Tests new keys in staging
- Updates JWKS
- Verifies relying parties can retrieve new keys
- Closes issue with execution summary
Lower-Risk Operations:
- GitHub issue for documentation
- Written rationale recorded before execution
- Post-execution verification noted
- Issue closed with summary
Emergency Exception:
- If the documented runbook cannot be followed in full during a security incident, proceed with the minimum necessary action
- Must document actions taken in the incident report immediately after
- Post-incident review required
Monitoring and Continuous Improvement
Effectiveness Metrics:
- Code Review Coverage. Target 100% (no self-merged PRs)
- Pre-Authorisation Compliance. Target 100% for critical operations (GitHub issue created and justified before execution)
- Audit Log Review Completion. Target 100% weekly reviews
- Access Review Timeliness. Target 100% within first week of quarter
- Failed Authentication Rate. Monitor for anomalies (>5 failures/hour)
Reviewed In:
- Quarterly Access Reviews. Check SoD controls still effective
- Internal Audits. Verify compensating controls operating as designed
- Management Review. Annual assessment of SoD adequacy
- Incident Post-Mortems. Identify if SoD gaps contributed to incident
Continuous Improvement:
- As team grows, implement additional segregation (separate DevOps, Security roles)
- Automate enforcement (e.g., GitHub Actions for dual approval verification)
- Expand audit logging coverage
- Enhance anomaly detection
Future Enhancements (when team size permits):
- Separate DevOps role (deploys only, does not develop)
- Dedicated Security Analyst (audits only, no operational access)
- Formal change advisory board (CAB) for production changes
- Automated dual-approval workflows (GitHub Actions + approval bots)
Acknowledgment of Risk
Residual Risk: Even with compensating controls, sole-operator segregation has inherent limitations:
- The single operator performs all sensitive functions
- No second person exists to independently verify actions in real time
- Separation of knowledge is not applicable
Risk Acceptance: This residual risk is accepted by ISMS Owner as proportionate to:
- Organisation size and resources
- Nature of business (age verification platform with ephemeral consumer data processing and no long-term personal data retention)
- Strength of compensating controls
- Transparent open source operations
- External audit oversight
Risk Re-evaluation: Quarterly (or sooner if team structure changes)
Documentation: This acknowledgment satisfies ISO 27001 A.5.3 requirement for small organisations with compensating controls.
Compliance
Failure to comply with this policy may result in:
- Mandatory security training
- Access restrictions
- Disciplinary action
- Termination (for severe violations)
All violations investigated and documented.
Related Documents
- Information Security Policy
- Acceptable Use Policy
- Cryptography Policy
- Roles and Responsibilities - Role definitions and RACI matrix
- Statement of Applicability - Controls A.5.3, A.5.9, A.8.1, A.8.2
Document Information
- Version. 1.1
- Effective Date. 2025-01-13
- Last Updated. 2026-05-21
- Owner. ISMS Owner
- Maintained By. Security Lead
- Review Frequency. Annually
- Next Review. 2026-11-21
- Classification. Public