Soon — Information Security Management System (ISMS)¶
This repository is the single source of truth for Soon's security policies and our path to ISO/IEC 27001:2022 certification (the primary goal), for the company and the Soon Workforce Management (WFM) SaaS platform. A SOC 2 report may follow later, reusing the same controls and evidence.
Everything is Markdown so it's easy to read, diff, review and process. We prepare and maintain every document through Claude Code — that's the main interface for both Olaf (internal) and Andrea (external consultant). A small script keeps the whole set valid and produces a live register and status dashboard.
- Policies only — never application code or secrets (kept in a separate repo).
- English only. Keep documents lean and practical — we're a small company.
1. Quick start (5 minutes)¶
What you need once¶
- Claude Code installed, opened in this repository folder.
- Python 3 + PyYAML (only needed to run the checker locally / it runs in CI too):
pip install pyyaml - Access to the GitHub repo (Olaf invites collaborators; auditors get read-only).
Your first commands¶
Open Claude Code in this folder and type:
/isms:onboard → new to the team, or your quarterly refresher (logs your training)
/isms:status → see where everything stands right now
/isms:gap → see what's missing for ISO 27001, prioritised
That's it. You don't need to know git — Claude Code does the file work for you. Team quick start (essentials + setup in 15 min): START-HERE.md · the rules in 5 minutes: ESSENTIALS.md
2. The everyday workflow¶
We do almost everything through eight commands. Type them in Claude Code:
| Command | Use it to… |
|---|---|
/isms:onboard |
New here, or quarterly refresher? Walks you through the essentials and logs your training |
/isms:status |
Rebuild the register/dashboard, validate, and summarise progress |
/isms:gap [iso\|soc2] |
Find missing controls/documents, prioritised (defaults to ISO) |
/isms:new <id> "<title>" |
Create a new document in the right place (e.g. the Statement of Applicability) |
/isms:draft <control/doc> |
Turn a raw template into a Soon-specific draft |
/isms:review <doc> |
Pressure-test a document the way an auditor will |
/isms:approve <doc> |
Record owner sign-off (status → approved, review date set) |
/isms:evidence <control> |
Verify a policy against the real app/infra (run in that repo) |
/isms:meeting |
Prep the weekly Thursday 13:00 CEST session |
A typical document goes: /isms:draft → answer the TODO(owner:) questions →
/isms:review → fix → /isms:approve. Only approved documents count toward
certification.
Prefer not to use Claude Code for a quick edit? You can edit any file directly on GitHub in the browser — see CONTRIBUTING.md. The commands just make it faster and consistent.
3. Browse it as a website (optional, nice for reading & auditors)¶
The repo is readable as-is on GitHub, but you can also render it as a searchable site:
pip install -r requirements-docs.txt # once
python3 tools/site.py serve # → http://127.0.0.1:8000
In Claude Code you can just run /isms:site. To host it privately behind a login
(Cloudflare Pages + Access — good for sharing read-only with an external auditor),
see docs/_reference/hosting-and-deploy.md.
4. Evidence — and why it lives in a different AWS account¶
Policies say what we do. Evidence proves we actually do it, and it is what an auditor samples. Policies live here in git; evidence artefacts live in S3 — in a different AWS account, deliberately.
Why not just keep it in the production account?¶
Because evidence that can be edited by the systems it describes is not evidence.
If the proof lived in production, anyone who compromised production could quietly delete the record of what they did — and we would have no way to show otherwise. Separating it means the credentials that run the product cannot touch the record of how the product is run. It is the same instinct as not letting the same person approve their own expenses.
The accounts¶
All five are in one AWS Organization, so there is one bill. Billing and access are separate things: being in the same organisation grants nobody access to anything.
| Account ID | Name | What it is |
|---|---|---|
| 742816139593 | Soon |
Production — the platform, the database, everything customers touch. Also the Organizations management account (see the caveat below) |
| 404379474355 | Soon-LogArchive |
The evidence store. In its own Security OU. Holds the S3 evidence bucket, the organisation CloudTrail destination and the isolated backup vault |
| 201756271125 | Soon-Development |
Development |
| 875770353832 | soon-development2 |
Development |
| 159066868234 | Soon-Scrio |
Separate workload — purpose to confirm with Melvin |
What protects the evidence¶
| Bucket | s3://soon-isms-evidence (eu-west-1) |
| Object Lock | GOVERNANCE, 1095 days — an object cannot be overwritten or deleted for three years, by anyone |
| Encryption | SSE-KMS, alias/soon-isms-evidence. The key trusts only principals inside the log-archive account |
| Guardrail | Service control policy ProtectSecurityLogs on the Security OU denies deleting the buckets, weakening Object Lock, bypassing retention, or changing the KMS key policy — even for a full administrator of that account |
Known caveat, stated plainly. Production is also the Organizations management account, and SCPs never apply to the management account. So the guardrail constrains
Soon-LogArchivebut notSoon. Combined withOrganizationAccountAccessRole— which grants a production admin full admin in the log-archive account — the honest reading is that account separation limits what an attacker could destroy, not where they could go. The SCP is what actually protects the evidence, and it does hold: attempts to change the bucket's encryption or the key policy are refused even with admin credentials.
You do not log in to the second account¶
There is no second password. Cross-account access works by role assumption: your production identity temporarily borrows a role in the other account and gets credentials that expire in an hour or two.
Two roles do this, both put-only:
soon-isms-evidence-capture— for people.tools/evidence.pyassumes it automatically, which is why capturing evidence works even though your own credentials are in production.soon-grc-evidence-writer— for CI, assumed by thesoon-grccollector via GitHub OIDC.
If evidence.py says it cannot assume the role, you are missing the
SoonIsmsEvidenceCaptureAssume policy on your IAM user — ask Olaf.
Capturing evidence¶
Most of the time you will not touch a terminal. Go to
isms.soon.works → SOC 2 → All 68 controls: every control has a card saying what to capture, with
an upload button under it. Screenshot with Cmd+Shift+3, upload, done. Your name and the
time come from the login, so there is nothing to fill in.
Set your clock to show the date once, so screenshots carry it:
defaults write com.apple.menuextra.clock DateFormat -string "EEE d MMM HH:mm:ss"
killall SystemUIServer
For command output rather than a screenshot — usually stronger evidence, because it is the raw truth and can be re-verified — there is a CLI:
cd ~/s/isms # NOT a .claude/worktrees/ copy
aws login
python3 tools/evidence.py check # is the store healthy?
python3 tools/evidence.py run --control A.8.20 --desc rds-not-public --soc2 44 --cc CC6.6 -- \
aws rds describe-db-instances --region eu-west-1
python3 tools/evidence.py add ~/Desktop/shot.png --control A.5.17 --desc mfa-github --soc2 34 --cc CC6.1
Either route hashes the artefact, files it in the write-once store, publishes a readable copy to the site and logs it. Auditors read it on the site — we do not send folders.
Uploads are permanent. Object Lock means a mistake cannot be deleted, only superseded by a better capture with a different
--desc. That is the point of the control, not a bug. Redact secrets and personal data before capturing, never after.
The other half — continuous checks¶
evidence.py is a photograph: a person captures a specific thing on a specific day.
That is what SOC 2 Type 1 tests, and it is the right tool for anything only a human can
capture — a console screenshot, a signed PDF, meeting minutes.
It cannot tell you whether the control is still true. A screenshot taken in September
proves nothing about December. That is the job of SoonHQ/soon-grc,
which runs ~29 read-only checks against AWS and GitHub every morning and writes the
result into the same evidence store — a heart monitor rather than a photograph.
Both are needed, and they do not overlap:
tools/evidence.py (here) |
soon-grc |
|
|---|---|---|
| Run by | a person, deliberately | a schedule, daily, nobody involved |
| Proves | this existed on this date | this is still true today, and every day since |
| Serves | SOC 2 Type 1 | SOC 2 Type 2, ISO 27001 clause 9.1 |
soon-grc gets more important after Type 1, not less: a Type 2 report is largely "show me this held for six months", which is exactly the history those daily runs accumulate.
Full detail: Evidence Collection & Management · Continuous Control Monitoring.
5. Where everything is¶
| If you want to… | Go to |
|---|---|
| Understand how we run this repo | MASTERPLAN.md |
| See the certification plan, timeline & every document we need | ROADMAP.md |
| See the live list of all documents | REGISTER.md (auto-generated) |
| See progress, % approved, overdue reviews | STATUS.md (auto-generated) |
| Understand what Soon is (context & ISMS scope) | docs/04-context/ISMS-04-01-context-and-scope.md |
| Learn how to contribute | CONTRIBUTING.md |
| See rules for AI assistants | AGENTS.md (Claude Code reads this) |
| Read the customer-facing security summary | docs/_reference/soon-security-overview.md |
6. Repository layout¶
.
├── README.md # you are here — how to use the repo
├── MASTERPLAN.md # operating model: how Olaf + Andrea run this via Claude Code
├── ROADMAP.md # certification plan + every document we need (with status)
├── REGISTER.md # live list of all documents ← auto-generated
├── STATUS.md # progress dashboard ← auto-generated
├── AGENTS.md # canonical instructions for AI assistants
├── CLAUDE.md # pointer to AGENTS.md (Claude Code entry point)
├── CONTRIBUTING.md # how to write/edit (incl. browser-only workflow)
│
├── docs/ # the ISMS, organised by ISO 27001 structure
│ ├── 04-context/ # Clause 4 — context & scope ✅ authored
│ ├── 05-leadership/ # Clause 5 — policy, roles, leadership
│ ├── 06-planning/ # Clause 6 — objectives, risk, Statement of Applicability
│ ├── 07-support/ # Clause 7 — competence, comms, documented information
│ ├── 08-operation/ # Clause 8 — operational planning & change
│ ├── 09-performance/ # Clause 9 — monitoring, internal audit, management review
│ ├── 10-improvement/ # Clause 10 — nonconformity & corrective action
│ ├── annex-a/ # Annex A controls: A5 Org · A6 People · A7 Physical · A8 Tech
│ ├── _templates/ # the document template to copy
│ └── _reference/ # security overviews, asset lists, source logs
│
├── .claude/commands/isms/ # the /isms:* slash commands
├── prompts/ # the same task prompts, for any AI tool
├── tools/isms.py # build (register + dashboard) & check (validation)
├── .github/workflows/ # CI: validates docs on every change
└── source/ # original .docx / .xlsx files (archived, read-only)
7. Document status legend¶
Used in REGISTER.md and STATUS.md:
- 📝 template — converted from a template, not yet tailored to Soon
- ✏️ draft — being written
- 👀 in-review — ready for the Thursday review
- ✅ approved — signed off by the owner; counts toward certification
- 🗄️ superseded / ➖ not-applicable — with justification
The authoritative plan and to-do list live in ROADMAP.md.
8. Behind the scenes (good to know, not required)¶
- Each document carries a YAML front-matter header (id, owner, status, version, control mappings, review dates, evidence). That metadata is what powers the register and dashboard.
python3 tools/isms.py buildregeneratesREGISTER.mdandSTATUS.md;python3 tools/isms.py checkvalidates the repo (the commands run these for you).- GitHub Actions runs the validator on every pull request and fails if the register is out of date — so nothing silently rots.
9. Context in one paragraph¶
Soon is a privately-held HRTech company (founded 2019) providing a cloud-based Workforce Management SaaS — scheduling, time & attendance, leave management, and AI-powered forecasting/auto-scheduling. It runs on AWS (eu-west-1, Ireland) with all customer data resident in the EU, operates as a GDPR data processor, and is delivered by a small, fully-remote team. The ISMS scope covers development, operation and support of that platform and its supporting cloud infrastructure. Full detail in the Context & Scope.