Skip to content

Security

Security Standards

Aligned to ISO/IEC 27001:2022. This document defines the operational controls in use. A full ISMS gap assessment should be conducted before formal certification pursuit.


Information Security Policy

Level147 is committed to protecting the confidentiality, integrity, and availability of information assets belonging to the business and its clients. All personnel (including contractors and AI-assisted tooling) operate under these controls.

Owner: Principal Consultant
Review: Annual minimum, or after any security incident


Asset Classification

ClassExamplesControls
ConfidentialClient credentials, API keys, personal data, financial recordsEncrypted at rest and in transit; access logged; never in version control
InternalArchitecture docs, infrastructure configs, internal commsAccess limited to authorised personnel; not published
PublicMarketing content, open-source code, public documentationNo restrictions

Access Control (ISO 27001 A.5.15–A.5.18)

Principle of Least Privilege

Every user, service account, and agent is granted only the minimum permissions required for its function. Admin access is never used for routine tasks.

Authentication

  • All production systems require MFA
  • SSH key authentication only — password auth disabled on all servers
  • SSH keys: Ed25519 minimum; RSA keys ≥ 4096-bit if required for compatibility
  • SSH keys rotated on personnel change or suspected compromise

Service Accounts

  • Each service has its own credential — no shared passwords between services
  • Supabase: anon key for client-side; service_role key only in server-side/CI contexts, never in frontend bundles
  • Woodpecker secrets injected at pipeline runtime; never logged

Access Review

Quarterly review of:

  • Supabase user roles
  • Gitea organisation members
  • Woodpecker admin access
  • Portainer access
  • Cloudflare account members

Secrets Management (ISO 27001 A.5.17)

Rules

  1. Never commit secrets. No API keys, passwords, tokens, or private keys in version control — ever.
  2. .env files are always gitignored. .env.example with placeholder values is committed.
  3. CI/CD secrets live in Woodpecker repo or organisation secrets, scoped to the minimum required pipelines.
  4. Secrets referenced in pipelines use the from_secret: directive — never inline plaintext.
  5. Long-lived tokens (Gitea PATs, Supabase service keys) are documented in the secrets inventory below.

Secrets Inventory

Maintain a private off-system record (e.g. Bitwarden) of:

SecretScopeRotation trigger
Gitea PAT (GITEA_TOKEN)Registry push/pullAnnual or on personnel change
Supabase service role keyServer-side writesAnnual or on breach
Woodpecker agent shared secretAgent ↔ server authOn agent re-enrolment or breach
Cloudflare API tokensDNS, R2Annual
SSH private keysServer accessOn device loss or personnel change

Network Security (ISO 27001 A.8.20–A.8.22)

Perimeter

  • All public-facing services sit behind Cloudflare (DDoS mitigation, WAF, TLS termination)
  • Internal services (Woodpecker gRPC port 9000, Portainer, Gitea) are not publicly exposed
  • Internal access via Tailscale overlay VPN only

Firewall Rules

  • Default deny inbound on all hosts
  • Explicit allow: 80/443 (Cloudflare only via CF IP ranges), 22 (SSH, key-auth only), Tailscale interface
  • Docker-published ports on internal hosts: bound to 127.0.0.1 or Tailscale interface, not 0.0.0.0

TLS

  • Minimum TLS 1.2; TLS 1.3 preferred
  • Cloudflare Full (Strict) mode — origin certificates must be valid
  • Internal service-to-service traffic on private networks may use HTTP if on Tailscale

Container Security (ISO 27001 A.8.9)

  • Container images pinned to explicit semver tags — never :latest in production
  • Images pulled from trusted registries only (gitea.level147.net, official Docker Hub images)
  • Resource limits set on all containers: CPU quota and memory limits in compose
  • Containers run as non-root where the image supports it
  • Docker socket mounts (/var/run/docker.sock) granted only to trusted infra agents (Woodpecker deploy agent, Portainer) — never to application containers

Vulnerability Management (ISO 27001 A.8.8)

  • Dependency updates reviewed monthly via npm audit / pip audit / equivalent
  • OS patches applied to all servers within 30 days of release; critical patches within 72 hours
  • Docker base images rebuilt on significant upstream releases
  • Known CVEs in dependencies escalated: High/Critical → address within sprint; Medium → next planned cycle

Logging and Monitoring (ISO 27001 A.8.15–A.8.16)

  • Container logs retained via Docker log driver; minimum 14-day retention
  • Supabase audit logs enabled for auth events
  • Woodpecker pipeline logs retained for 90 days
  • Cloudflare Analytics reviewed monthly for anomalies
  • Failed auth attempts and unusual API call volumes trigger manual investigation

Incident Response (ISO 27001 A.5.24–A.5.28)

Severity Classification

SeverityDefinitionResponse time
P1 — CriticalActive breach, data exfiltration, system unavailableImmediate
P2 — HighSuspected compromise, significant data exposure riskWithin 4 hours
P3 — MediumVulnerability identified, no active exploitWithin 48 hours
P4 — LowMinor issue, no immediate riskNext business day

Response Steps

  1. Contain — isolate affected system (revoke credentials, block IPs, take service offline if needed)
  2. Assess — determine scope: what was accessed, what data was exposed, time window
  3. Notify — if personal data is involved, assess Australian notifiable data breach obligations (see data-privacy.md)
  4. Remediate — patch, rotate credentials, rebuild from clean state if warranted
  5. Post-incident review — document root cause, update controls, review this standard

Credential Compromise Response

  1. Immediately revoke/rotate all affected credentials
  2. Audit logs for usage of compromised credential
  3. Redeploy affected services with new credentials
  4. Review how credential was exposed; update secrets management controls

Business Continuity (ISO 27001 A.5.29–A.5.30)

Backup Schedule

DataBackup frequencyRetentionLocation
Supabase databasesDaily (Supabase managed)7 days PITRSupabase cloud
Gitea repositoriesWeekly30 daysOff-site
Server configurationOn change (git)IndefiniteGitea
Docker volumes (stateful)Daily7 daysOff-site

Recovery Objectives

ObjectiveTarget
Recovery Time Objective (RTO)4 hours for production services
Recovery Point Objective (RPO)24 hours maximum data loss

Third-Party and Supply Chain (ISO 27001 A.5.19–A.5.22)

Key third-party dependencies and their security posture:

ProviderRoleNotes
SupabaseDatabase, auth, storageSOC 2 Type II; GDPR compliant; data in ap-southeast-1
CloudflareCDN, DNS, WAFSOC 2 Type II
TailscaleVPN overlaySOC 2 Type II; WireGuard-based
Gitea (self-hosted)Source control, registrySelf-managed; security is owner’s responsibility
n8n (self-hosted)Workflow automationSelf-managed; no external data sharing