# MySafeSigns — Essential Eight Maturity Self-Assessment

**Version:** 1.0
**Date:** 2026-04-28
**Owner:** SymbioTeK Pty Ltd (ACN 694 230 334)
**Framework:** Australian Cyber Security Centre (ACSC) Essential Eight Maturity Model

> **Honesty pledge:** this self-assessment uses the ACSC's published maturity criteria. We have not engaged an external assessor at v1. We declare maturity levels by strict reading of the ACSC criteria and document evidence; we do not round up. A SymbioTeK-funded ACSC-recognised assessment is on the roadmap (White Paper §10.2).
>
> **Threat model:** the App is a static web SaaS with no Windows endpoints, no Active Directory, and no on-premises deployment. Several Essential Eight strategies (designed for traditional Windows enterprise environments) map awkwardly. We document those mappings honestly rather than declaring them N/A.

---

## Summary

| # | Strategy | Current ML | 12-month target | Notes |
|---|---|---|---|---|
| 1 | Application control | ML0 | ML1 | Web-app sandbox + Content-Security-Policy approximate the intent. No traditional endpoint application control. |
| 2 | Patch applications | ML1 | ML1 | Dependency updates are tracked via Dependabot; deployed via PR within target windows for high-severity. |
| 3 | Configure Microsoft Office macro settings | N/A | N/A | No Office documents are part of the application surface. |
| 4 | User application hardening | ML1 | ML2 | Browser security headers (CSP, HSTS, X-Frame-Options) and SRI on third-party JS provide hardening at the application layer. |
| 5 | Restrict administrative privileges | ML1 | ML2 | Least-privilege via Supabase RLS + service-role key isolation. Operator MFA enforced. |
| 6 | Patch operating systems | N/A (inherited) | N/A | We operate no servers. OS patching inherited from AWS (Supabase), Stripe, Netlify. |
| 7 | Multi-factor authentication | ML1 | ML2 | TOTP MFA on all operator accounts. End-user MFA is on the roadmap (Supabase Auth supports it). |
| 8 | Regular backups | ML1 | ML2 | Supabase managed point-in-time recovery; user-controlled local backups optionally encrypted. |

**Overall posture:** ML0–ML1 across the strategies that apply to a static web SaaS. Target is ML1 across all applicable strategies within 12 months.

---

## 1. Application control

**ACSC intent:** prevent execution of unapproved/malicious programs.

**Application to a web SaaS:** the closest analogue is what scripts are allowed to run in the user's browser when using our app. Traditional endpoint application allow-listing does not apply.

**Current state (ML0–ML1):**
- Content-Security-Policy (`Security.md` §2.3) restricts script execution to `'self'` and `https://cdn.jsdelivr.net` (a single allow-listed CDN), plus `'unsafe-inline'` due to a known limitation (inline event handlers in legacy code).
- Sub-resource integrity (SRI) on the only third-party JavaScript dependency (Supabase SDK) prevents execution of a CDN-modified script.
- Operator devices: macOS Gatekeeper is enabled (default). No explicit application allow-list policy.

**Evidence:**
- `netlify.toml` — CSP header.
- `index.html` — SRI hash on Supabase script tag.

**Gap to ML2:** drop `'unsafe-inline'` from `script-src`. Scheduled 2026-05-28 (White Paper §10.2). After that, we hit ML1 cleanly.

## 2. Patch applications

**ACSC intent:** patch security vulnerabilities in applications within ACSC-defined windows.

**Application to MySafeSigns:**
- The application's runtime "applications" are: Supabase JS SDK, the Deno runtime in Edge Functions, Node tooling.
- The application's hosted "applications" are: Supabase platform, Netlify platform, Stripe API client, Anthropic API client.

**Current state (ML1):**
- GitHub Dependabot is enabled on the repository. High-severity advisories generate PRs.
- We commit to applying critical-severity patches within 48 hours of a Dependabot PR; high-severity within 14 days; medium within 30 days. This satisfies ML1 (which requires patching within 1 month for internet-facing services).
- Sub-processor patching is inherited from Supabase, Netlify, Stripe, Anthropic per their respective SOC 2 commitments.

**Gap to ML2:** an internet-facing service maturity-2 requires patching within 2 weeks for high-severity issues. Our committed window is already within this; documenting actuals against the commitment for 12 months will let us claim ML2 with evidence.

## 3. Configure Microsoft Office macro settings

**ACSC intent:** prevent malicious macros in Office documents.

**Application to MySafeSigns:** N/A. The App does not generate, consume, or process Office documents in its operational path. Marketing materials use Office formats but those are out of scope for the audit data path.

## 4. User application hardening

**ACSC intent:** harden user applications (browsers, PDF readers, Office) against exploitation.

**Application to MySafeSigns:** the app *is* a user application (a web app), so this is about hardening our app against attack.

**Current state (ML1):**
- Browser security headers: HSTS (2-year max-age, preload-eligible), Content-Security-Policy, X-Frame-Options DENY, Referrer-Policy strict-origin-when-cross-origin, Permissions-Policy restricting camera/geolocation to self.
- Sub-resource integrity (SRI) on third-party JavaScript.
- TLS 1.2+ enforced via HSTS.
- No Flash, ActiveX, Java applets, or other deprecated browser plugins are used.

**Evidence:** `netlify.toml`, `index.html`, `Security.md` §2.3.

**Gap to ML2:** ML2 requires periodic measurement of header compliance and CSP violation reports. We do not currently collect CSP reports. Adding a CSP `report-uri` directive and a small endpoint to capture violation reports is on the roadmap (Q3 2026).

## 5. Restrict administrative privileges

**ACSC intent:** restrict administrative privileges to those needed for personnel duties.

**Current state (ML1):**
- Supabase Row-Level Security forced on every user-data table. End-users can only read their own rows; only the service-role identity can write. The service-role key is held in Supabase's secret store and is accessible only to Edge Functions.
- Operator MFA enforced on all administrative accounts: Supabase, Stripe, GitHub, Netlify.
- The Supabase anon key (intentionally public) is RLS-constrained and cannot perform privileged operations.

**Evidence:** `Security.md` §2.5, `supabase/migrations/003_enforce_rls.sql`.

**Gap to ML2:** ML2 requires "privileged users use separate unprivileged accounts for non-privileged activities". At v1 the founder uses the same accounts for development and production. This will be addressed by introducing separate operator credentials for production work in Q2 2026.

## 6. Patch operating systems

**ACSC intent:** patch security vulnerabilities in operating systems.

**Application to MySafeSigns:** SymbioTeK operates no servers. Operating-system patching is inherited from AWS (Supabase), Stripe and Netlify per their published SOC 2 reports.

**Current state (Inherited from sub-processors):**
- Supabase: AWS-managed RDS and Edge Function runtime. AWS handles OS patching per their SOC 2 commitments.
- Netlify: Netlify-managed CDN nodes.
- Founder's operator devices: macOS with automatic security updates enabled.

**Evidence:** sub-processor SOC 2 reports, linked from the [sub-processor list](/security/sub-processors.html).

## 7. Multi-factor authentication

**ACSC intent:** require MFA for users authenticating to important services.

**Current state (ML1):**
- All operator accounts (Supabase, Stripe, GitHub, Netlify) have TOTP MFA enforced.
- End-user MFA is supported by Supabase Auth but is not enforced by the application at v1. End-users sign in with email + password.

**Evidence:** Supabase Auth configuration; operator account 2FA settings (screenshots available on request).

**Gap to ML2:** ML2 requires MFA for all users when accessing internet-facing services. Enabling end-user MFA via Supabase Auth (TOTP optional, gradually mandatory) is on the roadmap (Q3 2026). This is a pre-requisite for serving customers with strict identity-assurance requirements.

## 8. Regular backups

**ACSC intent:** perform regular backups, retain securely, test recovery, and protect against tampering.

**Current state (ML1):**
- **Supabase managed backups:** point-in-time recovery is enabled (default for the production Supabase plan). Retention: 7 days at v1; can be extended to 30 days via plan upgrade.
- **User-controlled backups:** Settings → Backup → Export produces a JSON file the user retains. Optional AES-256-GCM encryption with PBKDF2-SHA256 (250,000 iterations) and a user-supplied passphrase.
- **Code & configuration:** all infrastructure-as-code is in Git; redeployment from a clean state takes minutes.

**Evidence:** `js/backup.js`, `Security.md` §2.6, Supabase project settings.

**Gap to ML2:** ML2 requires that backups are tested for recoverability at least annually. Application redeployment is exercised on every push (implicit test). Supabase database restore from PITR has not been formally rehearsed at v1; scheduled for Q3 2026.

---

## Roadmap

Targets to claim ML1 across all applicable strategies by Q4 2026:

| Strategy | Action | Target date |
|---|---|---|
| 1 | Drop `'unsafe-inline'` from CSP `script-src` | 2026-05-28 (already scheduled) |
| 4 | Add CSP `report-uri` and capture CSP violation reports | Q3 2026 |
| 5 | Introduce separate operator credentials for production vs development | Q2 2026 |
| 7 | Enable optional end-user MFA via Supabase Auth | Q3 2026 |
| 8 | Formal annual restore-test of Supabase database PITR | Q3 2026 |

Targets to claim ML2 across applicable strategies are deferred to 2027 once ML1 is achieved consistently and external validation (pen test in Q3 2026, possible SOC 2 Type I in 2027) is in hand.

---

*Document version 1.0. Re-assessed annually or on material change. The current version of this self-assessment is at <https://mysafesigns.symbio-tek.com/security/Essential-Eight-Self-Assessment-v1.md>.*
