Every SOC 2 policy states a review cadence, usually annual, and auditors ask for evidence that each review happened on time. In most small companies, the review date lives in a Word file nobody opens until the auditor's request list arrives.
If your policies live in a repository as Markdown, you can make an overdue review fail CI, the same way a failing test does.
1. Put the policies in the repo.
npx github:odedmoshe/policyseed init # writes intake.yaml (23 questions)
npx github:odedmoshe/policyseed build # renders the 22 policies into policies/
The review cadence (annual, semi-annual or quarterly) is one setting in intake.yaml, and each rendered policy ends with a Revision History table (version, date, description, approved by). Adoption happens the same way it does in Word: management approves, and you record the approval as a new row in that table.
2. Check review dates on a schedule.
name: Policy review check
on:
schedule:
- cron: "0 9 * * 1"
workflow_dispatch: {}
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: odedmoshe/policyseed@v1
with:
command: check
policyseed check exits 1 when the newest date in a policy's revision history is older than the cadence allows, so the job goes red every Monday until someone reviews the policy and commits the new revision row.
3. Use git history as evidence. The pull request that updates the review date shows who reviewed, who approved and when. That's the record an auditor asks for, and you didn't have to build it separately.
What this doesn't do: it doesn't tell you whether the controls in the policy actually ran. Access reviews, restore tests and tabletop exercises still need their own records. It only makes sure the documents don't quietly go stale.
Disclosure: I maintain Policyseed. The templates, CLI and Action are Apache-2.0: https://github.com/odedmoshe/policyseed. There's also an MCP server if you'd rather have an assistant run the intake: claude mcp add policyseed -- npx -y github:odedmoshe/policyseed mcp.
Top comments (0)