Greenhat IMS template · DIY build guide
Build the IMS yourself
Step one
Tools you will need
docs/ into a searchable site. The menu comes from the folder tree; nothing is hand-maintained.main. Access puts a login in front of it.CLAUDE.md and AGENT_BRIEF.md in the repo.schemas/registers.schema.yml. An index of status and due dates, never the evidence.The system has no subscription. The documents are markdown in your own repository and the intranet is a static build of them. The one paid item is a Claude subscription. It pays for the agent that edits the documents, not for the system; cancel it and nothing stops working.
Step two
Create accounts
Listed in the order you will use them, with free-tier limits noted.
01Python 3.12 and Git
Install Python from python.org/downloads; on Windows tick Add python.exe to PATH. Install Git from git-scm.com. MkDocs runs on Python; VS Code needs Git 2.0 or later.
02GitHub
Sign up at github.com/signup.
Free tierUnlimited private repositories. 2,000 Actions minutes a month; the template’s checks run on every push and draw from them.
03Cloudflare
Sign up at dash.cloudflare.com/sign-up. Open Zero Trust, choose a team name and the Free plan. Payment details are requested at Zero Trust sign-up even on Free.
Free tierPages: 500 builds a month, one at a time, 20-minute build limit. Access: 50 users; a user takes a seat on first login and keeps it until you remove them.
04A domain on Cloudflare
The intranet hostname (ims.yourfirm.com.au) needs yourfirm.com.au as a zone in your Cloudflare account. On the Free plan that means moving the domain’s nameservers to Cloudflare: Add a domain, then change the nameservers at your registrar. If IT will not move them, register a separate domain for the intranet. Decide this now; Step five depends on it.
Cloudflare imports the records it can find when you add the domain. Before you change the nameservers at the registrar, compare its list with your current DNS, the MX and TXT records above all. A missing MX record stops your email.
Free tierFull setup only. CNAME setup, which leaves the nameservers where they are, needs a Business plan.
05VS Code
Download from code.visualstudio.com. Free.
06Claude
Sign up at claude.ai.
PaidClaude Code needs a Pro, Max, Team or Enterprise plan. The free plan does not include it.
On a Pro or Max plan, Anthropic may use your chats and coding sessions to train future models while the model-improvement setting is on, and keeps them for five years; with it off, thirty days. Everything the agent reads from this repository counts. Open claude.ai/settings/data-privacy-controls and switch the model-improvement setting (Help improve Claude) off, before the agent sees a single document. Team and Enterprise plans run under commercial terms: no training on your data unless you opt in.
Claude Code also sends usage metrics, error reports and session surveys of its own. One setting stops all of them. Put it in .claude/settings.json at the repository root and commit it, so every editor inherits it:
{ "env": { "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" } }
Two habits to go with it. Never run /feedback, /bug or /share from this repository: each uploads the session transcript, documents included, and Anthropic keeps it for five years. And on a shared computer, know that Claude Code keeps thirty days of session transcripts in plain text under ~/.claude/projects/.
If you are particularly squirrelly about handing your documents to an offshore IT company: you already do, if the firm’s files live in OneDrive, Google Drive or Dropbox, and Anthropic on commercial terms is no worse a custodian than any of them. If it still bothers you, the way out is a local model on a Mac mini in the server cupboard. That buys full data sovereignty at the price of about $5,000 of hardware and an agent noticeably dumber than the one $20 a month rents. Most firms take the $20.
07Airtable
Sign up at airtable.com/signup.
Free tier1,000 records a base, 5 editors, 1,000 API calls a workspace a month. MCP calls count as API calls. Scheduled email automations at realistic volumes need a paid tier.
Step three
Connect tools
Each connection is a one-time sign-in or a single command.
01VS Code to GitHub
Create an empty private repository at github.com/new. In VS Code open the Command Palette (Ctrl+Shift+P), run Git: Clone, paste the repository URL and sign in to GitHub in the browser when prompted. Optional: install the GitHub Pull Requests extension to review approval PRs in the editor.
02Cloudflare Pages to GitHub
In the Cloudflare dashboard: Workers & Pages, Create application, Pages, Connect to Git. Authorise GitHub for the IMS repository only. Set:
- Project name
yourfirm-ims(becomesyourfirm-ims.pages.dev)- Production branch
main- Framework preset
- MkDocs
- Build command
pip install -r requirements-docs.txt && mkdocs build --strict- Build output directory
site- Environment variable
PYTHON_VERSION=3.12
Save and Deploy. The first build fails until the template is pushed in Step four; expected.
03VS Code to Claude
Extensions (Ctrl+Shift+X), search Claude Code, install the Anthropic extension, open it and sign in with the account whose privacy setting you changed in Step two. Then install the CLI; the next step needs it.
irm https://claude.ai/install.ps1 | iex # Windows PowerShell curl -fsSL https://claude.ai/install.sh | bash # macOS, Linux claude --version
04Claude Code to Airtable
In a terminal inside the repository folder:
claude mcp add --transport http airtable https://mcp.airtable.com/mcp
In Claude Code type /mcp, choose airtable and complete the Airtable sign-in in the browser. For a team, commit .mcp.json at the repository root instead; each editor approves it once:
{ "mcpServers": { "airtable": { "type": "http", "url": "https://mcp.airtable.com/mcp" } } }
Use the official server only. MCP cannot create forms or switch on automations; formula fields are read-only; batch creates cap at 10 records.
Step four
Download the template
01Download the zip
The zip needs the accounts and connections from Steps one to three. If you have not done those, start at the top; the download stays here.
21 controlled documents, the register schema, the tooling and the agent briefs. Free and complete.
Download ims-template-v1.zip →
Licence text is inside the zip. Unzip it into the repository in the next step.
02Clone and unpack
git clone https://github.com/yourorg/yourfirm-ims.git ims cd ims # unzip ims-template-v1.zip here: mkdocs.yml and docs/ land at the top level python -m venv .venv .venv\Scripts\activate # macOS, Linux: source .venv/bin/activate pip install -r requirements-docs.txt mkdocs serve # http://127.0.0.1:8000
03Build
mkdocs build --strict
Must pass clean. It is the command Pages runs.
04Push
git add -A git commit -m "Adopt Greenhat IMS template v1" git push -u origin main
You run git yourself; the repository’s CLAUDE.md bars the agent from git writes. Pages builds on the push and the site is live at yourfirm-ims.pages.dev. What is live is the generic template, the same text as the public showcase; nothing of yours is in it. Your answers go in at Step six, after Step five secures the site so only your staff or authorised users can access it.
Step five
Deploy the intranet
A private repository, a build on every push, a login on your subdomain.
01Overview
main.ims.yourfirm.com.au.*.pages.dev URL must carry the same Access policy or be disabled, otherwise the custom-domain gate has an ungated back door.02Invite editors
Repository Settings, Collaborators, Add people. One invitation per editor. Readers are not invited; they get the intranet.
03Add the hostname
Workers & Pages, the project, Custom domains, Set up a domain: ims.yourfirm.com.au. Cloudflare writes the CNAME. Needs the zone from Step two.
04Add an identity provider
Zero Trust, Integrations, Identity providers, Add new, One-time PIN. For SSO instead, see 08.
05Restrict access to the hostname
Zero Trust, Access controls, Applications, Create, Self-hosted. Set:
- Public hostname
- domain
yourfirm.com.au, subdomainims - Policy
- Allow
- Include
- Emails ending in
@yourfirm.com.au - Identity provider
- One-time PIN
06Secure the pages.dev URL
Workers & Pages, the project, Settings, Enable access policy. That covers preview URLs only. Open the Access application it creates, edit the public hostname and remove the * subdomain so yourfirm-ims.pages.dev is covered too. Test both hostnames in a private window: both must show the Access login.
If yourfirm-ims.pages.dev opens without a login, the gate on ims.yourfirm.com.au is decoration. Cloudflare prints the pages.dev URL in the dashboard and in every build log, and it is guessable from the project name.
07Export the access log
Zero Trust, Logs, Access: who signed in, when, allowed or denied, by which provider. The Free plan keeps 24 hours. To have it at internal audit, pull the log on a schedule through the Access API into docs/records/.
08Choose a login method
User enters their work email. Access checks it against the allow rule and emails a one-time code.
No accounts, no passwords, no user directory. Zero admin. Ship this for small firms.
Access federates to your Microsoft 365 or Google Workspace tenant. Staff sign in with their existing work account. Offboarding is automatic: removed from the tenant, locked out of the docs.
Requires an app registration in your tenant (Entra ID or Google admin console) with redirect URI https://<team>.cloudflareaccess.com/cdn-cgi/access/callback. Entra ID client secrets expire; when one lapses nobody can sign in. Use when IT already manages identity.
Both options log who authenticated and when: controlled-access evidence at internal audit, subject to the retention in 07.
Step six
Customise the system
Add your organisation’s details, registers and documents, all behind the login.
Do not start this step until the test in Step five passes on both hostnames. Everything from here carries your answers: people, risks, legal duties, how the firm runs. Behind the login it is an intranet. In front of it, it is published.
01Answer the questionnaire
The template is full of blanks: your name, prefix and role titles, and an [ORG-DECISION] marker wherever a generic document would otherwise guess. The instantiation questionnaire gathers all of them on one sheet, twelve sections, about 110 questions, 2 to 3 hours in total. Each section names who answers it.
Do it as a meeting. Get the director, the operations lead, a worker representative and whoever does compliance in one room, work down the sheet aloud, and record it with a transcribing recorder app (Google Recorder on Android, Voice Memos on iOS). Where nobody knows, say LATER; a guess ends up in an audited document. Where a default is shown and it matches how you work, say so and move on.
The questionnaire is the planning. Sections F and J become the issues table, the risk registers and the objectives; section K is a full sitting with your senior staff. Nothing the agent invents to fill a gap is a decision you made. Book the sessions with the directors and the people who make the calls, work the sheet aloud, record every discussion and give the agent the complete transcripts, not a summary. The operations guide that follows assumes this was done and goes only as deep as your answers did; a glossed questionnaire is repaid there with interest.
Save the transcript as questionnaire-transcript.md at the repository root and add that filename to .gitignore. MkDocs publishes docs/ only, and the transcript is never committed.
02Populate the template
Open the folder in VS Code, open Claude Code and type:
Read docs/guides/instantiation-questionnaire.md, then questionnaire-transcript.md. Fill the questionnaire from the transcript, writing LATER where the answer is missing. Then read INSTANTIATION.md and start at step 1.
It builds org-profile.yml from the answers, runs python tools/instantiate.py to substitute every token, rewrite document IDs to your prefix and apply the capability flags, drafts the longer passages from what you said and nothing else, then --check must report zero unresolved tokens.
Before moving on, open org-profile.yml and check flags.mkdocs_site: true (the default is off) and publishing.repo_url. Anything you marked LATER stays in the documents as a visible marker: your tailoring worklist. Every draft lands through a pull request; the agent approves nothing, a named person merges.
03Build the registers
The registers index lists every table and field the base needs: 19 tables, from the Document Register and People through Risk, Hazard, Compliance Obligations and Incidents to the Schedule. Its source is schemas/registers.schema.yml; the live base is built from that file and later diffed against it. Step 2 of INSTANTIATION.md is the build. In Claude Code:
Run INSTANTIATION.md step 2: create the Airtable base from schemas/registers.schema.yml over MCP, every table and field, skipping tables whose flag is off.
The agent will ask before creating tables and rows in bulk. Read the list it shows you. Every call counts against the free tier’s 1,000 API calls a month, and a wrong base is quicker to delete than to repair.
Formula fields need the exact expressions in INSTANTIATION.md; the schema records only the intent. Then check the live base against the schema, with a personal access token from Airtable in AIRTABLE_PAT:
python tools/airtable_drift.py # zero diffs before continuing
Three forms and five automations cannot be created through the API. Configure them by hand in Airtable from the forms: and automations: blocks at the end of the schema file: Policy Acknowledgement, Training Completion and Hazard & Incident Report forms; the document review digest, acknowledgement campaign and reminder, training reminder, and review/audit programme prompt. Test each automation with a dummy row. Keep the form URLs; the reader guide and two of the emails need them.
Then seed, in this order: People; Training Curriculum; Document Register (the agent seeds it from frontmatter, all Draft); Schedule (12 management-review slices and 12 audit slices, plus the recurring obligations); Instruments & Commitments and their Compliance Obligations, from real jurisdiction sources with your compliance person, never invented by the agent; company-wide Objectives & Targets from the IMS Objectives & Improvement Plan. Offer-level objectives wait for a recorded management-review decision.
04Build
mkdocs build --strict
Must pass clean. It is the command Pages runs.
05Push
git add -A git commit -m "Instantiate IMS for Your Firm" git push -u origin main
Pages rebuilds behind the login. Open ims.yourfirm.com.au in a private window: the Access login first, then your documents.
Step seven
After setup
Once the system is live, these tasks are your responsibility.
01Ongoing tasks
docs/records/internal-audits/. Clause coverage of the programme is in the Audit Pack.docs/records/management-reviews/ at the interval your procedure sets.mkdocs-material is pinned in requirements-docs.txt. MkDocs 2.0 breaks it. Bump deliberately, after mkdocs build --strict passes locally.02Now what?
The build is the rough-in. The next procedure takes the system into use: every document reviewed and approved by the people who live under it, the first offer defined with the people who buy it, the risk registers rated in the room, and a quarter of records from live work.
03Next steps
Add the clause maps
All 104 obligations tied to the document, section and statement. One-time.
GuidedWe instruct, you build
Two set-up sessions, clause maps, registers built, a monthly check-in.
ManagedWe run it
A named Greenhat quality manager carries every duty above.
Documentation, not legal, safety or compliance advice. No ISO standard text is reproduced; you need licensed copies of the standards. Certification depends on your arrangements and your certification body’s assessment. The template is governed by its disclaimer and terms of use.