ISMS Copilot Docs

Run your GRC from GitHub with Claude and ISMS Copilot: the five-part setup we run

The setup we run our own ISMS with: a grc/ folder in GitHub, Claude Code as the operating agent, a GRC platform as the record auditors read, ISMS Copilot to ask, draft with and review, heyGRC on every pull request, plus the deterministic checks and dated reminders that hold it together. Each part explained, with the files that matter shown.

This guide shows the setup we run our own ISMS with, from GitHub, with Claude Code and ISMS Copilot working as one team. It has five parts: a grc/ folder next to the code, Claude Code as the agent that does the work, a GRC platform that holds the record your auditor reads, ISMS Copilot to ask, draft with and review every compliance draft like an auditor would, and heyGRC on every pull request. Deterministic checks and dated reminders hold the five together.

The split is the same as in the rest of this series. Claude does the legwork: reading, comparing, drafting, cross-checking. ISMS Copilot, connected inside Claude, answers the compliance questions, drafts with Claude and challenges each draft before it is final. You decide what is in scope, which risks you accept, what is effective and what gets signed.

We have been building this since February 2026 for our own ISO 27001 preparation. We are working towards ISO/IEC 27001:2022 certification. We do not claim a certificate before it is granted.

Who this fits. Teams whose product and daily work already live in GitHub: an in-house ISMS team of two to five people next to engineers. If you are a consultant with several clients, or a team without engineers, most of the value carries over without CI: one folder per client, the same three ISMS Copilot moments, the same habit of keeping dates in the records. Start with Run your ISMS with Claude and ISMS Copilot, which needs only a folder.

Why this split

The work of running an ISMS happens where the company already works. For a software company that is the repository: a change to access, logging, a supplier or a data flow lands there first. So the ISMS documents live there too, written and reviewed like code, with history and review built in.

A GRC platform is still worth having, for the things a database and a UI do better than a folder: suppliers and their reviews, controls and their status, findings with owners and due dates, and an approval trail an auditor can open without a GitHub account. In this setup the platform holds that record. Git stays the source of every document, and the platform receives a copy.

The agent is the operator between the two. Claude Code reads the folder, follows the procedures written in it, and calls ISMS Copilot at the steps those procedures name. Nothing in the setup depends on the agent saying "done": every step that matters has a check that does not take its word for it.

The map

            you decide, approve, sign
                      │
      ┌───────────────┴────────────────┐
      │                                │
 GitHub: grc/ folder  ── one-way ──▶  GRC platform
 (source of documents,   sync         (the record auditors read:
  registers, procedures)              suppliers, controls, findings,
      │                               approvals)
      │ read, draft, propose
      ▼
 Claude Code ◀── ask, draft, review ──▶ ISMS Copilot
 (does the work, follows grc/)          (the GRC expert it calls)
      │
      │ opens pull requests
      ▼
 heyGRC + CI checks on every pull request
 (did this change miss a compliance requirement?
  are the records complete and consistent?)

Part 1: the grc/ folder

The ISMS lives in a grc/ folder of the repository where the product is built, not in a separate tool and not in someone's drive. A change to a policy is a pull request, reviewed like any other.

grc/
├── README.md                  which standard clause lives in which folder
├── isms-core/                 scope, context, interested parties, SoA,
│                              objectives, document control, internal audit
│                              programme, management review, calendar
├── policies/                  or at the repository root, if your engineers
│                              already know where to find them
├── procedures/                how recurring work is done, step by step
├── risks/                     one file per risk
├── data-protection/           processing register, impact and transfer
│                              assessments, supplier DPAs
├── security-reviews/          one dated record per change that needs one
├── reports/                   audit reports, risk reviews, access reviews,
│                              management review packs
├── nc-ofi-register.md         nonconformities and improvements: root cause,
│                              action, effectiveness
├── incident-register.md       incidents and what was reported to whom
└── src/                       the small scripts the CI checks run

Three choices make the rest of the setup work:

  • One file per risk (risks/R-0042.yaml) instead of one spreadsheet. A risk change is then a one-file diff that a reviewer, a script and the agent can all read.
  • Every document carries its own header: owner, version, last updated, next review, classification, standard reference. The header is what the checks and the reminders read.
  • One index (isms-core/master-reference.md) lists every policy, procedure and core document. A document is not part of the ISMS until it is indexed, and a check enforces it. Your auditor can still sample anything in the repository, so the index has to be complete, not just tidy.

Keep the repository private. The registers describe your weak points.

grc/policies/access-control.md (header)
---
owner: Head of Engineering
version: 1.4
last_updated: 2026-10-02
next_review: 2027-04-02
classification: Internal
iso_reference: ISO/IEC 27001:2022 A.5.15, A.5.18, A.8.2
---

Part 2: Claude Code, following grc/

Claude Code is the operating agent. When it does engineering work in the repository, the same instructions tell it how the ISMS works, so a change that touches a control produces the record it needs in the same pull request.

The repository's agent instructions (CLAUDE.md, or AGENTS.md for other agents) carry the few rules that tie engineering to the ISMS:

AGENTS.md (excerpt)
## GRC
The ISMS lives in grc/. Read grc/README.md before touching it.

- A change that touches authentication, data access, prompts, billing,
  secrets or a new supplier needs a dated record in grc/security-reviews/
  with verdict Approved before customers get it.
- Every pull request body carries one line:
  Security review: <record path> | N/A - <reason> | pending
- You may draft in grc/ and open a pull request. You never approve,
  publish or sign. Policies and the SoA merge only after their owner has
  reviewed the exact change; the named approver then publishes it.
- Recurring work follows the procedure in grc/procedures/. Do the steps
  in order. Where a step says "ISMS Copilot", call it.
- Never write that a control is implemented, effective or compliant.
  Write what the evidence shows; the owner concludes.

The procedures are where the ISMS work is really defined. A procedure is a short Markdown file the agent follows step by step, with the ISMS Copilot moments written into it:

grc/procedures/quarterly-risk-review.md (excerpt)
## Steps
1. List every risk in grc/risks/ whose review_date is past or within
   14 days.
2. For each one, read the incidents, findings and supplier changes since
   the last review (grc/nc-ofi-register.md, grc/security-reviews/, git log).
3. Draft the proposed changes (likelihood, impact, treatment status) as a
   diff in a pull request. Never change an owner or an acceptance decision.
4. ISMS Copilot: send the draft for review, think mode. Ask what an
   auditor would challenge and what the standard expects that is missing.
5. Fold in the review. Quote any point you did not take, with the reason.
6. Assign the pull request to each risk owner. The review is complete when
   they merge it with one line of rationale per risk, not when you open it.

Step 6 is the one that matters most. The agent prepares the review; the owner's merge is the decision. That decision rests on your risk method and your risk acceptance criteria, both approved documents in isms-core/ before the first review, so an owner can say why they accepted a score, not just that they did.

Part 3: the GRC platform, the record auditors read

The platform holds what is better kept in a database than in files, and what your auditor will open: suppliers and their reviews, the controls and the SoA, measures, risks, open findings with their due dates, and the approval trail. Open-source and commercial platforms both work for this part.

Two rules keep it from becoming a second truth:

  • Git is the source for documents. A policy is written and reviewed in git: the merge settles the text. The formal approval is one act in one place: the named approver publishes that version in the platform, where the auditor sees it, after checking that the platform draft matches the merged text. A text changed after approval goes back through the same path.
  • The sync goes one way. A scheduled job copies grc/ from the main branch to the platform through its API. It never writes back into git. It refuses to run from a local working copy or from a source older than a week, so it never imports unmerged or stale text. What the auditor sees as current is controlled by the other half: the sync only creates drafts, and only the named approver can publish, sign or delete.

What we sync: policies and core ISMS documents (as drafts awaiting publication), suppliers and their assessments, processing activities, the controls and SoA, measures, assets, risks, and open nonconformities as findings with their due dates. What we do not sync: security review records and internal working notes. They are documented information too, so they stay under the same control in git (dated, versioned, on a protected branch), and when an auditor asks for them we show them from the repository.

If the platform has no usable API, keep the same rule by hand: git first, then the platform, with the git commit noted in the platform's version comment.

Part 4: ISMS Copilot, at the steps the procedures name

Claude and ISMS Copilot work as one team. Claude does the legwork in your files; ISMS Copilot is the GRC expert it calls, over MCP, inside the same session, at three moments:

  • Ask. When a step depends on what a standard or a law requires (a control's intent, how NIS 2 applies in a given country, which edition is current), Claude asks ISMS Copilot rather than answering from memory, and keeps the source and its date in the output.
  • Draft. When a document needs compliance judgement (a policy section, an SoA justification, a risk treatment), Claude drafts it with ISMS Copilot.
  • Review and challenge. Before a draft is final, Claude sends it to ISMS Copilot for review: errors, outdated references, what an auditor would challenge, what is missing.

The routing rule that makes this happen sits where the agent reads it at the start of every session. We keep ours in the user-level ~/.claude/CLAUDE.md, so it applies in every repository we work in; a team can put it in the repository's CLAUDE.md or AGENTS.md instead. The procedures then name the step, so the call happens at the same point every time, not when the agent happens to think of it.

Connect it once:

claude mcp add --scope user --transport http ismscopilot https://account.ismscopilot.com/v1/account/mcp

Run /mcp, pick ismscopilot, sign in and click Approve. The routing rule, what to send and what never to send: ISMS Copilot in Claude and ChatGPT, and when to call it.

Part 5: heyGRC on every pull request

The first four parts keep the ISMS documents right. heyGRC covers the other direction: a change shipped in the product that should have touched the ISMS and did not. It reviews the pull request diff and reports when the change affects something your ISO 27001, SOC 2 or GDPR programme cares about (access, data flows, logging, suppliers, change management) and the evidence is missing.

Your own rules go in a .heygrc.md file at the repository root, written as controls: the control and clause, the trigger, the evidence the pull request must carry, the gap to report.

.heygrc.md (excerpt)
# Example Co

Example Co runs a multi-tenant SaaS on EU infrastructure.

## Supplier control (ISO 27001 A.5.19, A.5.20)
A pull request that adds a new external API, SDK or subprocessor is a
supplier change. It must link the supplier review in
grc/data-protection/ and say whether the processing register was updated.
If it does not, that is a supplier-management gap to report.

## International transfers (GDPR Art. 44 to 46)
A change that adds or moves a data store, queue or model provider outside
the EEA, or gives a provider access to personal data from outside the EEA
(support or admin access included), must link a transfer assessment.
Missing, it is a gap to report.

We run it on every pull request into the release branch, and on request on day-to-day branches. heyGRC reports; it does not block merges. Blocking is done by our own release gate, described in the next section. How to write rules it will actually raise: Writing team rules heyGRC can check.

The deterministic checks

The five parts are only as good as the checks around them. An agent will sometimes say a step is done when it is not. So nothing important depends on its word: each rule an agent could quietly skip has a check in CI that does not.

.github/workflows/grc-checks.yml
name: grc-checks
on: pull_request
jobs:
  checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22 }
      - name: Document headers and index
        run: node grc/src/doc-check.mjs
      - name: Risk register
        run: node grc/src/validate-risks.mjs grc/risks
      - name: Security review line
        env:
          BODY: ${{ github.event.pull_request.body }}
        run: |
          printf '%s\n' "$BODY" | tr -d '\r' \
            | grep -Eq '^Security review: (grc/security-reviews/[A-Za-z0-9_-][A-Za-z0-9._-]*\.md|N/A - [^ ].*|pending)$' \
            || { echo "The PR body needs a 'Security review:' line."; exit 1; }

It runs on every pull request, not only on changes to grc/, because the changes that need a security review are product changes. validate-risks.mjs is yours to write, because it encodes your own risk method.

What the checks enforce in our setup:

  • Document headers. Every policy, procedure and core document has owner, version, last updated, next review, classification and standard reference. A missing field fails the pull request.
  • The index. Every document is listed in the master reference, and every listed path points to a file that exists.
  • The risk register. Every risk file has the required fields, a score that matches the method, an owner, and a review date.
  • The security review line. Every pull request says which review record covers it, why none is needed, or that one is pending.
  • The release gate. On pull requests into the release branch, one more check of ours reads heyGRC's result: if heyGRC flagged the release, the check fails until the record named on the Security review: line exists with verdict Approved. heyGRC itself only reports; this gate is what blocks. We do not show it here, because it depends on how you read the review result in your CI.

The header and index check is the smallest and the most useful. The index lists each document by its path in backticks, for example `grc/policies/access-control.md`:

grc/src/doc-check.mjs
import { readFileSync, readdirSync, existsSync } from "node:fs";
import { join } from "node:path";

const REQUIRED = ["owner", "version", "last_updated", "next_review",
  "classification", "iso_reference"];
const DIRS = ["grc/policies", "grc/procedures", "grc/isms-core"];
const INDEX = "grc/isms-core/master-reference.md";

const listed = new Set(
  [...readFileSync(INDEX, "utf8").matchAll(/`(grc\/[^`]+\.md)`/g)].map((m) => m[1]));
let failed = 0;
const fail = (msg) => { console.error(msg); failed++; };

for (const dir of DIRS) {
  const files = readdirSync(dir, { recursive: true }).filter((f) => f.endsWith(".md"));
  for (const name of files) {
    const path = join(dir, name);
    const head = readFileSync(path, "utf8").match(/^---\r?\n([\s\S]*?)\r?\n---/);
    const fields = head ? head[1] : "";
    for (const key of REQUIRED) {
      if (!new RegExp(`^${key}:[ \\t]*\\S`, "m").test(fields)) fail(`${path}: missing ${key}`);
    }
    if (path !== INDEX && !listed.has(path)) fail(`${path}: not listed in ${INDEX}`);
  }
}
for (const path of listed) {
  if (!existsSync(path)) fail(`${INDEX}: ${path} does not exist`);
}
process.exit(failed ? 1 : 0);

On the agent side, a hook in Claude Code adds one hard stop where CI comes too late: before the agent runs a command that turns a change on in production, the hook checks that the change's security review record has verdict Approved, and blocks the command if not. Ours is specific to how we deploy, so it is not shown here. The pattern for a hook that guards signed records is in File 6 of the folder guide.

The dated reminders

An ISMS is mostly recurring work: risk reviews, document reviews, supplier reviews, corrective actions with due dates, access reviews, the management review. Each one is easy. Keeping all of them on time, every month, is where the energy goes.

The rule that makes it manageable: the date lives in the record, and one list collects every date.

  • A document's next_review is in its header.
  • A risk's review_date and treatment due dates are in its file.
  • A nonconformity's target date is in the register.
  • Recurring duties with no single record (the management review, the internal audit, the access review) go in one calendar file:
grc/isms-core/isms-calendar.yaml
lead_days: 14
duties:
  - id: access-review
    every: quarter
    next: 2026-12-15
    owner: Head of Engineering
    procedure: grc/procedures/access-review.md
  - id: management-review
    every: year
    next: 2027-02-10
    owner: CEO
    procedure: grc/procedures/management-review.md
  - id: supplier-review
    every: year
    next: 2027-01-20
    owner: Head of Operations
    procedure: grc/procedures/supplier-review.md
  - id: internal-audit
    every: year
    next: 2027-01-12
    owner: Internal auditor
    procedure: grc/isms-core/internal-audit-programme.md

A procedure says what each duty must produce. The management review pack is built from the inputs the standard lists (audit results, risk treatment status, objectives, nonconformity trends, feedback from interested parties) and its decisions are minuted. The supplier review covers the contract's security terms and how the service actually performed, not only a fresh questionnaire. A nonconformity closes only after its root cause is recorded and the effectiveness of the action has been checked.

Each weekday morning, a small script reads every date from these places and writes one list: overdue first, then everything due within the lead time, each with its owner and its procedure. That list feeds the daily and weekly priorities. Each item gets one of three answers the same day: done (with the record that proves it), re-dated (with the reason, written into the record), or started (the agent runs the procedure and opens a pull request for the owner).

The script is deterministic on purpose. Collecting dates is not a judgement call, and you want the same list whether or not an agent ran that morning. The agent comes in afterwards, to do the work the list points to.

A first week

  1. Day 1. Create grc/ in your product repository. Move your policies and core documents in, add the header to each, and write the master reference.
  2. Day 1. Add the GRC section to AGENTS.md or CLAUDE.md. Connect ISMS Copilot and let the setup write the routing rule.
  3. Day 2. Add the header and index check to CI. Fix what it finds: that list is your first document-control backlog.
  4. Day 3. Write one procedure you run every quarter (the risk review is a good first one) with the ISMS Copilot steps in it. Run it once with Claude, review the pull request like a colleague's draft.
  5. Day 4. Put the dates in the records and the recurring duties in the calendar file. Write the collector and look at the list it gives you.
  6. Day 5. Install heyGRC on the repository and write two rules in .heygrc.md for the changes you most often forget to record. If you use a GRC platform, decide what it receives from git and set up the one-way sync, or the manual equivalent.

What still takes work

Two things took us the most effort, and they will for you too.

Chasing. The routines that chase due actions, nonconformities, risk reviews and document reviews do not build themselves. Without the dated list and the procedures, you end up prompting the agent all day, item by item, and remembering what is due is still your job. Budget real time for the reminders and the procedures: they are what turns an agent that can help into a setup that runs every week.

Trust. You cannot take an agent's "done" at face value. It will sometimes report a step complete that it skipped, or a check passed that it never ran. Every rule that matters needs something that does not depend on the agent: a CI check, a required record, a hook, an owner's merge. Write the rule first, then add the check the first time it is skipped.

What stays yours

The setup prepares decisions; it does not take them. Scope, risk acceptance, the SoA, the judgement that a control works, publishing a policy, what you tell an auditor and what you sign: those stay with named people, and those people need the competence to judge what the agent drafts. The setup moves work off them, not responsibility. The agent opens the pull request; the owner's merge or publication is the decision.

For internal audits, the agent can assemble the evidence and draft the checklist, but someone independent of the work being audited owns the audit. If an agent maintains your registers, a person who did not run that work audits them.

Connect ISMS Copilot to Claude

The repository, the checks and the reminders work without us. What Claude x ISMS Copilot adds is the expert step at the points your procedures name: ask it what the standard or the law requires, draft with it, and have it review and challenge every draft like an auditor would, from framework modules kept current with their edition and verification dates.

Connect ISMS Copilot to Claude Code, claude.ai or Claude Desktop, then add heyGRC to your repository from the heyGRC documentation.

On this page