open-agreements 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/content/templates/closing-checklist/metadata.yaml +6 -13
- package/content/templates/closing-checklist/template.docx +0 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +47 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/checklist.d.ts +21 -1
- package/dist/commands/checklist.d.ts.map +1 -1
- package/dist/commands/checklist.js +175 -44
- package/dist/commands/checklist.js.map +1 -1
- package/dist/commands/recipe.js +3 -11
- package/dist/commands/recipe.js.map +1 -1
- package/dist/core/checklist/index.d.ts +22 -14
- package/dist/core/checklist/index.d.ts.map +1 -1
- package/dist/core/checklist/index.js +79 -39
- package/dist/core/checklist/index.js.map +1 -1
- package/dist/core/checklist/jsonl-stores.d.ts +3 -0
- package/dist/core/checklist/jsonl-stores.d.ts.map +1 -0
- package/dist/core/checklist/jsonl-stores.js +16 -0
- package/dist/core/checklist/jsonl-stores.js.map +1 -0
- package/dist/core/checklist/schemas.d.ts +2 -2
- package/dist/core/checklist/schemas.js +1 -1
- package/dist/core/checklist/schemas.js.map +1 -1
- package/dist/core/checklist/state-manager.d.ts +146 -0
- package/dist/core/checklist/state-manager.d.ts.map +1 -0
- package/dist/core/checklist/state-manager.js +147 -0
- package/dist/core/checklist/state-manager.js.map +1 -0
- package/dist/core/checklist/status-labels.d.ts +6 -0
- package/dist/core/checklist/status-labels.d.ts.map +1 -0
- package/dist/core/checklist/status-labels.js +29 -0
- package/dist/core/checklist/status-labels.js.map +1 -0
- package/dist/core/validation/recipe.d.ts.map +1 -1
- package/dist/core/validation/recipe.js +47 -61
- package/dist/core/validation/recipe.js.map +1 -1
- package/package.json +1 -1
- package/skills/cloud-service-agreement/SKILL.md +9 -0
- package/skills/data-privacy-agreement/SKILL.md +9 -0
- package/skills/delaware-franchise-tax/SKILL.md +56 -19
- package/skills/delaware-franchise-tax/reference/ecorp-portal-playwright-notes.md +136 -0
- package/skills/edit-docx-agreement/CONNECTORS.md +20 -0
- package/skills/edit-docx-agreement/SKILL.md +77 -0
- package/skills/employment-contract/SKILL.md +9 -0
- package/skills/iso-27001-evidence-collection/CONNECTORS.md +23 -0
- package/skills/iso-27001-evidence-collection/SKILL.md +300 -0
- package/skills/iso-27001-evidence-collection/rules/api-exports.md +191 -0
- package/skills/iso-27001-evidence-collection/rules/evidence-types.md +107 -0
- package/skills/iso-27001-evidence-collection/rules/screenshot-guide.md +77 -0
- package/skills/iso-27001-internal-audit/CONNECTORS.md +23 -0
- package/skills/iso-27001-internal-audit/SKILL.md +272 -0
- package/skills/iso-27001-internal-audit/rules/access-control.md +191 -0
- package/skills/iso-27001-internal-audit/rules/business-continuity.md +94 -0
- package/skills/iso-27001-internal-audit/rules/change-management.md +211 -0
- package/skills/iso-27001-internal-audit/rules/encryption.md +93 -0
- package/skills/iso-27001-internal-audit/rules/incident-response.md +127 -0
- package/skills/iso-27001-internal-audit/rules/isms-management.md +164 -0
- package/skills/iso-27001-internal-audit/rules/logging-monitoring.md +96 -0
- package/skills/iso-27001-internal-audit/rules/people-controls.md +161 -0
- package/skills/iso-27001-internal-audit/rules/supplier-management.md +92 -0
- package/skills/nda/SKILL.md +9 -0
- package/skills/open-agreements/SKILL.md +9 -0
- package/skills/safe/SKILL.md +9 -0
- package/skills/services-agreement/SKILL.md +9 -0
- package/skills/soc2-readiness/CONNECTORS.md +23 -0
- package/skills/soc2-readiness/SKILL.md +289 -0
- package/skills/soc2-readiness/rules/trust-services.md +230 -0
- package/skills/venture-financing/SKILL.md +9 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Delaware eCorp Portal — Playwright Automation Notes
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
### Launch Chrome with remote debugging
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Must quit Chrome first, then relaunch with debug port
|
|
9
|
+
osascript -e 'tell application "Google Chrome" to quit'
|
|
10
|
+
sleep 2
|
|
11
|
+
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
|
|
12
|
+
--remote-debugging-port=9222 \
|
|
13
|
+
--user-data-dir=/tmp/chrome-debug-profile &
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Connect via Playwright (CDP)
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
NODE_OPTIONS='--no-deprecation' uv run python3 << 'PYEOF'
|
|
20
|
+
from playwright.sync_api import sync_playwright
|
|
21
|
+
with sync_playwright() as p:
|
|
22
|
+
browser = p.chromium.connect_over_cdp("http://localhost:9222")
|
|
23
|
+
ctx = browser.contexts[0]
|
|
24
|
+
page = ctx.pages[0]
|
|
25
|
+
PYEOF
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Fixes & Gotchas
|
|
29
|
+
|
|
30
|
+
### 1. Readonly "Total Issued Shares" field
|
|
31
|
+
- `gridStock_ctl02_txtIssuedShares` is **readonly** — it's auto-summed from per-class fields
|
|
32
|
+
- Fill the per-class field instead: `gridStock_ctl02_gridStockDetails_ctl02_txtIssuedShares`
|
|
33
|
+
- This populates the readonly total automatically on recalculate
|
|
34
|
+
|
|
35
|
+
### 2. Asset Date field mangles input with Playwright .fill()/.type()
|
|
36
|
+
- The date field has a mask/formatter that garbles Playwright keyboard input
|
|
37
|
+
- **Fix**: Use JavaScript to set the value directly:
|
|
38
|
+
```python
|
|
39
|
+
page.evaluate('''
|
|
40
|
+
const el = document.getElementById('ctl00_ContentPlaceHolder1_gridStock_ctl02_txtAssetDate');
|
|
41
|
+
el.value = '12/31/2025';
|
|
42
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
43
|
+
''')
|
|
44
|
+
```
|
|
45
|
+
- The portal requires asset date == fiscal year end date, or it ignores gross assets
|
|
46
|
+
|
|
47
|
+
### 3. APVC method activation
|
|
48
|
+
- Portal defaults to Authorized Shares method ($85,165 for 10M shares)
|
|
49
|
+
- To get APVC: fill issued shares + gross assets + correct asset date, then click "Recalculate Tax"
|
|
50
|
+
- If asset date doesn't match fiscal year end, recalculate silently stays on Authorized Shares
|
|
51
|
+
|
|
52
|
+
### 4. ASP.NET ViewState breaks on back-navigation
|
|
53
|
+
- Never use `page.go_back()` — the ViewState expires and you get a server error
|
|
54
|
+
- Always start fresh from the login page: `https://icis.corp.delaware.gov/ecorp/logintax.aspx`
|
|
55
|
+
|
|
56
|
+
### 5. Postback links (2024 "File Amended Annual Report")
|
|
57
|
+
- The link is `javascript:__doPostBack(...)`, not a real URL
|
|
58
|
+
- Can't open in a new tab via href — must execute on the page
|
|
59
|
+
- Use: `page.evaluate("__doPostBack('ctl00$ContentPlaceHolder1$lnkPrevAR','')")`
|
|
60
|
+
|
|
61
|
+
### 6. CAPTCHA
|
|
62
|
+
- Field: `#ctl00_ContentPlaceHolder1_ecorpCaptcha1_txtCaptcha`
|
|
63
|
+
- Image: `#ctl00_ContentPlaceHolder1_ecorpCaptcha1_captchaImage` (NOT `img[src*='Captcha']`)
|
|
64
|
+
- Case-insensitive in practice (all caps in image)
|
|
65
|
+
- Screenshot cropping can be unreliable — fetch the CAPTCHA image bytes via JS `fetch()` on `img.src` as fallback
|
|
66
|
+
|
|
67
|
+
### 7. Key field selectors
|
|
68
|
+
| Field | Selector ID (after ctl00_ContentPlaceHolder1_) |
|
|
69
|
+
|-------|------------------------------------------------|
|
|
70
|
+
| File number | txtPrimaryFileNo |
|
|
71
|
+
| CAPTCHA | ecorpCaptcha1_txtCaptcha |
|
|
72
|
+
| Continue button | btnContinue |
|
|
73
|
+
| Issued shares (per-class) | gridStock_ctl02_gridStockDetails_ctl02_txtIssuedShares |
|
|
74
|
+
| Issued shares (total, readonly) | gridStock_ctl02_txtIssuedShares |
|
|
75
|
+
| Gross assets | gridStock_ctl02_txtGrossAsset |
|
|
76
|
+
| Asset date | gridStock_ctl02_txtAssetDate |
|
|
77
|
+
| Fiscal year end | txtFiscalYearEndYear |
|
|
78
|
+
| Recalculate button | btnRecalucation (note: typo in portal) |
|
|
79
|
+
| Continue Filing button | btnProceedPayment |
|
|
80
|
+
| Enter Directors button | btnDisplayDirectorForm |
|
|
81
|
+
| Nature of Business | ddlBusinessNatures |
|
|
82
|
+
|
|
83
|
+
### 8. State dropdowns use abbreviations (NY, WA, etc.)
|
|
84
|
+
- All state dropdowns (`drpHidePrincipal`, `drpHideOfficer`, `drpHideAuthor`, `drpDirectorStatesN`) use 2-letter state codes
|
|
85
|
+
- Use `page.select_option("#drpHidePrincipal", value="NY")` — NOT `label="New York"`
|
|
86
|
+
|
|
87
|
+
### 9. Director form fields (inline, not popup)
|
|
88
|
+
- Click `#btnDisplayDirectorForm` to reveal director rows
|
|
89
|
+
- **CRITICAL**: Director names have THREE separate fields per director:
|
|
90
|
+
- `txtDirectorName{N}` = **first name only** (NOT full name!)
|
|
91
|
+
- `txtMiddleName{N}` = middle name/initial
|
|
92
|
+
- `txtLastName{N}` = last name (REQUIRED — validation fails without it)
|
|
93
|
+
- Other fields: `txtDirectorAddress{N}`, `txtDirectorCity{N}`, `drpDirectorStates{N}`, `txtDirectorZip{N}`, `drpDirectorCountry{N}`
|
|
94
|
+
- Numbered 1–N based on `txtTotalNumOfDirectors`
|
|
95
|
+
- All use simple IDs (no ASP.NET prefix)
|
|
96
|
+
|
|
97
|
+
### 10. Tax result label IDs (different from what you'd expect)
|
|
98
|
+
| Label | Selector ID (after ctl00_ContentPlaceHolder1_) |
|
|
99
|
+
|-------|------------------------------------------------|
|
|
100
|
+
| Franchise Tax | lblFranchisetaxData |
|
|
101
|
+
| Penalty | lblPenaltyData |
|
|
102
|
+
| Interest | lblMonthlyIntrestData |
|
|
103
|
+
| Filing Fee | lblAnnualFilingDta |
|
|
104
|
+
| Credit | lblPreviousData |
|
|
105
|
+
| Prepaid | lblPrepaidPaymentData |
|
|
106
|
+
| **Total Due** | **lblAmountDue** |
|
|
107
|
+
|
|
108
|
+
### 11. Officer and Authorization address fields
|
|
109
|
+
| Section | Street | City | State | Zip |
|
|
110
|
+
|---------|--------|------|-------|-----|
|
|
111
|
+
| Principal | txtStreetPrincipal | txtCityPrincipal | drpHidePrincipal | txtZipPrincipal |
|
|
112
|
+
| Officer | txtStreetOfficer | txtCityOfficer | drpHideOfficer | txtZipOfficer |
|
|
113
|
+
| Auth | txtStreetAuthorization | txtCityAuthorization | drpHideAuthor | txtZipAuthorization |
|
|
114
|
+
|
|
115
|
+
### 12. Session/eId behavior
|
|
116
|
+
- Dashboard URL needs `eId` parameter from login — can't bookmark dashboard directly
|
|
117
|
+
- **BUT**: Cmd+Back (browser history) in a new tab CAN get back to dashboard within the same session
|
|
118
|
+
- Each login generates a unique eId; session cookies are shared across tabs
|
|
119
|
+
|
|
120
|
+
### 13. T&C checkbox required before Continue Filing
|
|
121
|
+
- Must check `#ctl00_ContentPlaceHolder1_chkCertify` before clicking Continue Filing
|
|
122
|
+
- Validation error: "Authorization: Please check the box to confirm that you have read the Terms and Conditions"
|
|
123
|
+
|
|
124
|
+
### 14. Confirmation page — save BEFORE navigating away
|
|
125
|
+
- **"Once you leave this screen, you will no longer be able to obtain a confirmation copy"**
|
|
126
|
+
- **PDF download**: `downloadConfirmation()` → opens `DownLoadConfirmation.ashx?srNo=...&fileNo=...`
|
|
127
|
+
- Triggers a file download, NOT a page navigation — Playwright will throw "Download is starting" error (that's OK, the file downloads)
|
|
128
|
+
- **Email confirmation**: `openARemail()` → opens `Email.aspx?srNo=...` popup
|
|
129
|
+
- Fill `#txtEmailAddress` and `#txtVerifyEmailAddress`, click `#btnEmail`
|
|
130
|
+
- Response: "Your e-mail request has been received. Please allow 48 hours."
|
|
131
|
+
- Service Request Number is in the URL: `?srNo=XXXXXXXXXXX`
|
|
132
|
+
|
|
133
|
+
### 15. Deprecation warning
|
|
134
|
+
- `[DEP0169] url.parse() behavior is not standardized` comes from Playwright's Node.js internals
|
|
135
|
+
- Harmless — Playwright uses `url.parse()` in its server; fix is upstream (Playwright issue)
|
|
136
|
+
- Suppress with: `NODE_OPTIONS='--no-deprecation'` env var
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Connectors
|
|
2
|
+
|
|
3
|
+
## OpenAgreements (for template filling)
|
|
4
|
+
|
|
5
|
+
Use the standard OpenAgreements connectors (remote MCP or local CLI) for fill operations.
|
|
6
|
+
See https://github.com/open-agreements/open-agreements/blob/main/skills/open-agreements/CONNECTORS.md for details.
|
|
7
|
+
|
|
8
|
+
## Safe Docx MCP (for surgical DOCX editing)
|
|
9
|
+
|
|
10
|
+
Safe Docx is a **separate MCP server** that must be configured independently.
|
|
11
|
+
It is not part of the OpenAgreements skill set.
|
|
12
|
+
|
|
13
|
+
The user must have Safe Docx MCP already set up in their agent environment.
|
|
14
|
+
If Safe Docx tools are not available, instruct the user to:
|
|
15
|
+
|
|
16
|
+
1. Visit https://github.com/UseJunior/safe-docx for setup instructions
|
|
17
|
+
2. Configure the Safe Docx MCP server in their agent's MCP settings
|
|
18
|
+
3. Restart their agent session
|
|
19
|
+
|
|
20
|
+
Do not instruct the agent to download or install packages at runtime.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: edit-docx-agreement
|
|
3
|
+
description: >-
|
|
4
|
+
Make bespoke edits to a DOCX agreement generated by OpenAgreements (or any existing DOCX),
|
|
5
|
+
using Safe Docx MCP tools for surgical, formatting-preserving edits and tracked-changes outputs.
|
|
6
|
+
license: MIT
|
|
7
|
+
compatibility: >-
|
|
8
|
+
Works with any agent. Requires a separately configured Safe Docx MCP server for document editing.
|
|
9
|
+
OpenAgreements fill capabilities require the OpenAgreements remote MCP or local CLI.
|
|
10
|
+
metadata:
|
|
11
|
+
author: open-agreements
|
|
12
|
+
version: "0.2.0"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# edit-docx-agreement
|
|
16
|
+
|
|
17
|
+
Use this skill when a user asks for **custom edits that are not exposed as template fields** in an OpenAgreements-generated (or any existing) DOCX agreement.
|
|
18
|
+
|
|
19
|
+
> **Interactivity note**: Always ask the user for missing inputs (file path, change intent, output preferences).
|
|
20
|
+
|
|
21
|
+
## Security model
|
|
22
|
+
|
|
23
|
+
This skill bridges two separate systems:
|
|
24
|
+
- **OpenAgreements** (remote MCP or local CLI) — for template filling. Follows the OpenAgreements zero-download security model.
|
|
25
|
+
- **Safe Docx** (local MCP server) — for surgical DOCX editing. Requires separate setup. This is **not** part of the OpenAgreements skill set and has its own trust/security model.
|
|
26
|
+
|
|
27
|
+
The agent must have Safe Docx MCP tools available to perform edits. If Safe Docx tools are not detected, inform the user and provide setup guidance (see Connectors).
|
|
28
|
+
|
|
29
|
+
## Decision rule: refill vs edit vs both
|
|
30
|
+
|
|
31
|
+
1. **Field-only changes** (e.g., party name, date, amount, valuation cap):
|
|
32
|
+
Re-run OpenAgreements `fill_template` with the updated field values. No Safe Docx needed.
|
|
33
|
+
|
|
34
|
+
2. **Boilerplate-only changes** (e.g., custom clause, modified standard language):
|
|
35
|
+
Use Safe Docx MCP tools to surgically edit the existing DOCX.
|
|
36
|
+
|
|
37
|
+
3. **Mixed changes** (field updates + bespoke edits):
|
|
38
|
+
Re-fill via OpenAgreements first (to get a clean base with updated fields), save the output locally, then use Safe Docx to apply bespoke edits on the fresh file.
|
|
39
|
+
|
|
40
|
+
## Execution
|
|
41
|
+
|
|
42
|
+
### Step 0: Confirm you have a local .docx file path
|
|
43
|
+
|
|
44
|
+
- If OpenAgreements was run via remote MCP, the fill response returns a download URL (with `expires_at`). Save the DOCX to a local path immediately.
|
|
45
|
+
- If the download link has expired, re-run `fill_template` to get a fresh URL.
|
|
46
|
+
- If OpenAgreements was run via local CLI, use the output file path directly.
|
|
47
|
+
|
|
48
|
+
### Step 1: Verify Safe Docx MCP is available
|
|
49
|
+
|
|
50
|
+
Check whether Safe Docx tools (e.g., `read_file`, `replace_text`, `apply_plan`) are available in the current session.
|
|
51
|
+
|
|
52
|
+
- **If available**: proceed to Step 2.
|
|
53
|
+
- **If not available**: inform the user that Safe Docx MCP is required for bespoke edits and provide setup instructions from the Connectors file. Stop here until the user configures it.
|
|
54
|
+
|
|
55
|
+
### Step 2: Apply the decision rule
|
|
56
|
+
|
|
57
|
+
Follow the routing logic above (field-only / boilerplate-only / mixed).
|
|
58
|
+
|
|
59
|
+
For Safe Docx edits:
|
|
60
|
+
- Use `read_file` to locate target paragraphs
|
|
61
|
+
- Use `replace_text` or `insert_paragraph` for surgical changes
|
|
62
|
+
- Use `apply_plan` for batch edits (fails safely if any step is invalid)
|
|
63
|
+
- Re-read edited paragraphs to verify changes
|
|
64
|
+
|
|
65
|
+
### Step 3: Deliver reviewable outputs
|
|
66
|
+
|
|
67
|
+
Use Safe Docx `download` to save:
|
|
68
|
+
- A **tracked-changes** DOCX for legal review
|
|
69
|
+
- A **clean** DOCX for signing (optional but recommended)
|
|
70
|
+
|
|
71
|
+
Summarize edits for the user (paragraph IDs, before/after text).
|
|
72
|
+
|
|
73
|
+
## Licensing note
|
|
74
|
+
|
|
75
|
+
Some templates (notably YC SAFEs) are licensed under CC-BY-ND-4.0. You can fill them for your own use but must not redistribute modified versions of the template itself. The filled output may constitute an "adapted work" — do not redistribute your filled output publicly without reviewing the license terms. See `docs/licensing.md` for details.
|
|
76
|
+
|
|
77
|
+
This tool does not provide legal advice — consult an attorney.
|
|
@@ -155,3 +155,12 @@ Use `list_templates` (MCP) or `list --json` (CLI) for the latest inventory and f
|
|
|
155
155
|
- OpenAgreements employment templates are licensed under CC-BY-4.0
|
|
156
156
|
- These templates are designed for US at-will employment — state-specific laws may apply
|
|
157
157
|
- This tool does not provide legal advice — consult an attorney
|
|
158
|
+
|
|
159
|
+
## Bespoke edits (beyond template fields)
|
|
160
|
+
|
|
161
|
+
If you need to edit boilerplate or add custom language that is not exposed as a template field,
|
|
162
|
+
use the `edit-docx-agreement` skill to surgically edit the generated DOCX and produce a
|
|
163
|
+
tracked-changes output for review. This requires a separately configured Safe Docx MCP server.
|
|
164
|
+
|
|
165
|
+
Note: templates licensed under CC-BY-ND-4.0 (e.g., YC SAFEs) can be filled for your own use
|
|
166
|
+
but must not be redistributed in modified form.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Connectors
|
|
2
|
+
|
|
3
|
+
## How tool references work
|
|
4
|
+
|
|
5
|
+
This skill uses `~~category` placeholders for optional integrations. The skill works without any connectors configured — they enhance the experience when available.
|
|
6
|
+
|
|
7
|
+
## Connectors for this skill
|
|
8
|
+
|
|
9
|
+
| Category | Placeholder | Recommended server | Other options |
|
|
10
|
+
|----------|-------------|-------------------|---------------|
|
|
11
|
+
| Compliance data | `~~compliance` | Compliance MCP server (planned — not yet available) | Local `compliance/` directory files |
|
|
12
|
+
|
|
13
|
+
### Local compliance data (current default)
|
|
14
|
+
|
|
15
|
+
If the `compliance/` directory exists with evidence status files, the skill reads those directly. No MCP server needed — just ensure evidence files in `compliance/evidence/*.md` are up to date.
|
|
16
|
+
|
|
17
|
+
### Compliance MCP server (planned)
|
|
18
|
+
|
|
19
|
+
A dedicated compliance MCP server with automated gap detection and evidence freshness tracking is planned but not yet available. When released, it will be installable as a standard MCP server. Until then, the skill operates in local-data or reference-only mode.
|
|
20
|
+
|
|
21
|
+
### Fallback: Reference only
|
|
22
|
+
|
|
23
|
+
Without any connector, the skill uses embedded checklists and CLI command reference. No organization-specific evidence status is available in this mode.
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: iso-27001-evidence-collection
|
|
3
|
+
description: >-
|
|
4
|
+
Collect, organize, and validate evidence for ISO 27001 and SOC 2 audits.
|
|
5
|
+
API-first approach with CLI commands for major cloud platforms. Produces
|
|
6
|
+
timestamped, auditor-ready evidence packages.
|
|
7
|
+
license: MIT
|
|
8
|
+
compatibility: >-
|
|
9
|
+
Works with any AI agent. Enhanced with compliance MCP server for automated
|
|
10
|
+
gap detection. Falls back to embedded checklists when no live data available.
|
|
11
|
+
metadata:
|
|
12
|
+
author: open-agreements
|
|
13
|
+
version: "0.1.0"
|
|
14
|
+
frameworks:
|
|
15
|
+
- ISO 27001:2022
|
|
16
|
+
- SOC 2 Type II
|
|
17
|
+
- NIST SP 800-53 Rev 5
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# ISO 27001 Evidence Collection
|
|
21
|
+
|
|
22
|
+
Systematically collect audit evidence for ISO 27001:2022 and SOC 2. This skill provides API-first evidence collection commands, organizes evidence by control, and validates completeness before auditor review.
|
|
23
|
+
|
|
24
|
+
## Security Model
|
|
25
|
+
|
|
26
|
+
- **No scripts executed** — this skill is markdown-only procedural guidance
|
|
27
|
+
- **No secrets required** — works with reference checklists; CLI commands use existing local credentials
|
|
28
|
+
- **Evidence stays local** — all outputs go to the local filesystem
|
|
29
|
+
- **IP-clean** — references NIST SP 800-53 (public domain); ISO controls cited by section ID only
|
|
30
|
+
|
|
31
|
+
## When to Use
|
|
32
|
+
|
|
33
|
+
Activate this skill when:
|
|
34
|
+
|
|
35
|
+
1. **Preparing evidence package for external audit** — 2-4 weeks before auditor arrives
|
|
36
|
+
2. **Quarterly evidence refresh** — update evidence that has aged beyond the audit window
|
|
37
|
+
3. **After remediation** — collect evidence proving a finding has been fixed
|
|
38
|
+
4. **New system onboarding** — establish baseline evidence for a newly in-scope system
|
|
39
|
+
5. **Evidence gap analysis** — identify what's missing before the audit
|
|
40
|
+
|
|
41
|
+
Do NOT use for:
|
|
42
|
+
- Running the internal audit itself — use `iso-27001-internal-audit`
|
|
43
|
+
- SOC 2-only readiness assessment — use `soc2-readiness`
|
|
44
|
+
- Interpreting audit findings — use the internal audit skill
|
|
45
|
+
|
|
46
|
+
## Core Concepts
|
|
47
|
+
|
|
48
|
+
### Evidence Hierarchy (Best to Worst)
|
|
49
|
+
|
|
50
|
+
| Rank | Type | Example | Why Better |
|
|
51
|
+
|------|------|---------|------------|
|
|
52
|
+
| 1 | **API export (JSON/CSV)** | `gcloud iam service-accounts list --format=json` | Timestamped, tamper-evident, reproducible |
|
|
53
|
+
| 2 | **System-generated report** | SOC 2 report from vendor, SIEM export | Authoritative source, includes metadata |
|
|
54
|
+
| 3 | **Configuration export** | Terraform state, policy JSON | Shows intended state, version-controlled |
|
|
55
|
+
| 4 | **Screenshot with system clock** | `screencapture -x ~/evidence/...` | Visual proof, but harder to validate |
|
|
56
|
+
| 5 | **Manual attestation** | Signed statement by responsible person | Last resort, requires corroboration |
|
|
57
|
+
|
|
58
|
+
### Evidence Freshness Requirements
|
|
59
|
+
|
|
60
|
+
| Evidence Type | Max Age | Refresh Cadence |
|
|
61
|
+
|---------------|---------|-----------------|
|
|
62
|
+
| Access lists | 90 days | Quarterly |
|
|
63
|
+
| Vulnerability scans | 30 days | Monthly |
|
|
64
|
+
| Configuration exports | 90 days | Quarterly |
|
|
65
|
+
| Training records | 12 months | Annual |
|
|
66
|
+
| Penetration test | 12 months | Annual |
|
|
67
|
+
| Policy documents | 12 months | Annual review |
|
|
68
|
+
| Incident records | Audit period | Continuous |
|
|
69
|
+
| Risk assessment | 12 months | Annual + on change |
|
|
70
|
+
|
|
71
|
+
### Evidence Naming Convention
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
{control_id}_{evidence_type}_{YYYY-MM-DD}.{ext}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Examples:
|
|
78
|
+
- `A.5.15_user-access-list_2026-02-28.json`
|
|
79
|
+
- `A.8.8_vulnerability-scan_2026-02-28.csv`
|
|
80
|
+
- `A.8.13_backup-test-results_2026-02-28.pdf`
|
|
81
|
+
|
|
82
|
+
## Step-by-Step Workflow
|
|
83
|
+
|
|
84
|
+
### Step 1: Identify Evidence Gaps
|
|
85
|
+
|
|
86
|
+
Determine what evidence is missing or stale.
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
# If compliance MCP is available:
|
|
90
|
+
list_evidence_gaps(framework="iso27001_2022", tier="critical")
|
|
91
|
+
|
|
92
|
+
# If reading local compliance data:
|
|
93
|
+
# Check compliance/evidence/*.md files for upload_status != "OK"
|
|
94
|
+
# Check renewal_next dates for upcoming expirations
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 2: Prioritize Collection
|
|
98
|
+
|
|
99
|
+
Order evidence collection by:
|
|
100
|
+
1. **Missing evidence for Critical-tier controls** — audit blockers
|
|
101
|
+
2. **Stale evidence past renewal date** — auditor will reject
|
|
102
|
+
3. **Evidence for Relevant-tier controls** — expected but not blocking
|
|
103
|
+
4. **Checkbox-tier evidence** — policies and attestations
|
|
104
|
+
|
|
105
|
+
### Step 3: Collect by Platform
|
|
106
|
+
|
|
107
|
+
Run evidence collection commands grouped by platform to minimize context-switching.
|
|
108
|
+
|
|
109
|
+
#### GitHub Evidence
|
|
110
|
+
```bash
|
|
111
|
+
# Org settings: MFA requirement, default permissions
|
|
112
|
+
gh api orgs/{org} | jq '{
|
|
113
|
+
two_factor_requirement_enabled,
|
|
114
|
+
default_repository_permission,
|
|
115
|
+
members_can_create_public_repositories
|
|
116
|
+
}' > evidence/A.5.17_github-org-mfa_$(date +%Y-%m-%d).json
|
|
117
|
+
|
|
118
|
+
# Branch protection on production repos
|
|
119
|
+
for repo in $(gh repo list {org} --json name -q '.[].name'); do
|
|
120
|
+
gh api repos/{org}/$repo/branches/main/protection 2>/dev/null | \
|
|
121
|
+
jq '{repo: "'$repo'", protection: .}' >> evidence/A.8.32_branch-protection_$(date +%Y-%m-%d).json
|
|
122
|
+
done
|
|
123
|
+
|
|
124
|
+
# Recent merged PRs (change management evidence)
|
|
125
|
+
gh pr list --state merged --limit 50 --json number,title,author,reviewDecision,mergedAt,mergedBy \
|
|
126
|
+
> evidence/A.8.32_change-records_$(date +%Y-%m-%d).json
|
|
127
|
+
|
|
128
|
+
# Dependabot alerts (vulnerability management)
|
|
129
|
+
gh api repos/{org}/{repo}/dependabot/alerts?state=open \
|
|
130
|
+
> evidence/A.8.8_dependabot-alerts_$(date +%Y-%m-%d).json
|
|
131
|
+
|
|
132
|
+
# Secret scanning alerts
|
|
133
|
+
gh api orgs/{org}/secret-scanning/alerts --paginate \
|
|
134
|
+
> evidence/A.8.24_secret-scanning_$(date +%Y-%m-%d).json
|
|
135
|
+
|
|
136
|
+
# Audit log
|
|
137
|
+
gh api orgs/{org}/audit-log?per_page=100 \
|
|
138
|
+
> evidence/A.8.15_github-audit-log_$(date +%Y-%m-%d).json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### GCP Evidence
|
|
142
|
+
```bash
|
|
143
|
+
# IAM policy (access control)
|
|
144
|
+
gcloud projects get-iam-policy {project} --format=json \
|
|
145
|
+
> evidence/A.5.15_gcp-iam-policy_$(date +%Y-%m-%d).json
|
|
146
|
+
|
|
147
|
+
# Service accounts
|
|
148
|
+
gcloud iam service-accounts list --format=json \
|
|
149
|
+
> evidence/A.5.16_gcp-service-accounts_$(date +%Y-%m-%d).json
|
|
150
|
+
|
|
151
|
+
# Audit logging config
|
|
152
|
+
gcloud projects get-iam-policy {project} --format=json | jq '.auditConfigs' \
|
|
153
|
+
> evidence/A.8.15_gcp-audit-config_$(date +%Y-%m-%d).json
|
|
154
|
+
|
|
155
|
+
# Log sinks (centralization)
|
|
156
|
+
gcloud logging sinks list --format=json \
|
|
157
|
+
> evidence/A.8.15_gcp-log-sinks_$(date +%Y-%m-%d).json
|
|
158
|
+
|
|
159
|
+
# Compute instances (asset inventory)
|
|
160
|
+
gcloud compute instances list --format=json \
|
|
161
|
+
> evidence/A.5.9_gcp-compute-inventory_$(date +%Y-%m-%d).json
|
|
162
|
+
|
|
163
|
+
# Cloud SQL backup config
|
|
164
|
+
gcloud sql backups list --instance={instance} --format=json \
|
|
165
|
+
> evidence/A.8.13_gcp-sql-backups_$(date +%Y-%m-%d).json
|
|
166
|
+
|
|
167
|
+
# Firewall rules
|
|
168
|
+
gcloud compute firewall-rules list --format=json \
|
|
169
|
+
> evidence/A.8.20_gcp-firewall-rules_$(date +%Y-%m-%d).json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Azure Evidence
|
|
173
|
+
```bash
|
|
174
|
+
# Role assignments (access control)
|
|
175
|
+
az role assignment list --all --output json \
|
|
176
|
+
> evidence/A.5.15_azure-role-assignments_$(date +%Y-%m-%d).json
|
|
177
|
+
|
|
178
|
+
# Activity log (audit trail)
|
|
179
|
+
az monitor activity-log list --max-events 100 --output json \
|
|
180
|
+
> evidence/A.8.15_azure-activity-log_$(date +%Y-%m-%d).json
|
|
181
|
+
|
|
182
|
+
# Network security groups
|
|
183
|
+
az network nsg list --output json \
|
|
184
|
+
> evidence/A.8.20_azure-nsgs_$(date +%Y-%m-%d).json
|
|
185
|
+
|
|
186
|
+
# Backup jobs
|
|
187
|
+
az backup job list --resource-group {rg} --vault-name {vault} --output json \
|
|
188
|
+
> evidence/A.8.13_azure-backup-jobs_$(date +%Y-%m-%d).json
|
|
189
|
+
|
|
190
|
+
# Storage encryption
|
|
191
|
+
az storage account list --query "[].{name:name, encryption:encryption}" --output json \
|
|
192
|
+
> evidence/A.8.24_azure-storage-encryption_$(date +%Y-%m-%d).json
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Google Workspace Evidence
|
|
196
|
+
```bash
|
|
197
|
+
# User list with MFA status
|
|
198
|
+
gam print users fields primaryEmail,name,isEnrolledIn2Sv,isEnforcedIn2Sv,lastLoginTime,suspended \
|
|
199
|
+
> evidence/A.5.17_workspace-users-mfa_$(date +%Y-%m-%d).csv
|
|
200
|
+
|
|
201
|
+
# Admin roles
|
|
202
|
+
gam print admins > evidence/A.8.2_workspace-admins_$(date +%Y-%m-%d).csv
|
|
203
|
+
|
|
204
|
+
# Mobile devices
|
|
205
|
+
gam print mobile > evidence/A.8.1_workspace-mobile-devices_$(date +%Y-%m-%d).csv
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### macOS Endpoint Evidence
|
|
209
|
+
```bash
|
|
210
|
+
# FileVault encryption
|
|
211
|
+
fdesetup status > evidence/A.8.24_filevault-status_$(date +%Y-%m-%d).txt
|
|
212
|
+
|
|
213
|
+
# System configuration
|
|
214
|
+
system_profiler SPHardwareDataType SPSoftwareDataType \
|
|
215
|
+
> evidence/A.8.1_endpoint-config_$(date +%Y-%m-%d).txt
|
|
216
|
+
|
|
217
|
+
# Screen lock settings
|
|
218
|
+
profiles show -type configuration 2>/dev/null | grep -A10 -i "lock\|idle\|screensaver" \
|
|
219
|
+
> evidence/A.6.7_screenlock-config_$(date +%Y-%m-%d).txt
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Step 4: Validate Evidence Package
|
|
223
|
+
|
|
224
|
+
Check completeness before submitting to auditor:
|
|
225
|
+
|
|
226
|
+
1. **Completeness**: Do you have evidence for every applicable control in the SoA?
|
|
227
|
+
2. **Freshness**: Is every piece of evidence within the required age?
|
|
228
|
+
3. **Format**: Are API exports in JSON/CSV with timestamps? Screenshots have system clock visible?
|
|
229
|
+
4. **Naming**: Files follow the naming convention?
|
|
230
|
+
5. **Coverage**: Critical-tier controls have at least 2 forms of evidence?
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
# If compliance MCP is available:
|
|
234
|
+
list_evidence_gaps(framework="iso27001_2022") # Should return empty for complete package
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Step 5: Generate Evidence Index
|
|
238
|
+
|
|
239
|
+
Create an index file listing all evidence, mapped to controls:
|
|
240
|
+
|
|
241
|
+
```markdown
|
|
242
|
+
# Evidence Package Index
|
|
243
|
+
Generated: {date}
|
|
244
|
+
Audit period: {start} to {end}
|
|
245
|
+
|
|
246
|
+
| Control | Evidence File | Type | Collected | Status |
|
|
247
|
+
|---------|--------------|------|-----------|--------|
|
|
248
|
+
| A.5.15 | gcp-iam-policy_2026-02-28.json | API export | 2026-02-28 | Current |
|
|
249
|
+
| A.5.17 | workspace-users-mfa_2026-02-28.csv | API export | 2026-02-28 | Current |
|
|
250
|
+
| ... | ... | ... | ... | ... |
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## DO / DON'T
|
|
254
|
+
|
|
255
|
+
### DO
|
|
256
|
+
- Use API exports with ISO 8601 timestamps over screenshots whenever possible
|
|
257
|
+
- Collect evidence from the SOURCE system (IdP, not a secondary report)
|
|
258
|
+
- Include metadata: collection date, system version, user who collected
|
|
259
|
+
- Store evidence in version-controlled directory with clear naming
|
|
260
|
+
- Collect evidence for the AUDIT PERIOD (usually past 12 months), not just current state
|
|
261
|
+
- Use `screencapture -x ~/evidence/{filename}.png` for screenshots (captures without shadow/border)
|
|
262
|
+
|
|
263
|
+
### DON'T
|
|
264
|
+
- Take screenshots without visible system clock (menu bar on macOS, taskbar on Windows)
|
|
265
|
+
- Collect evidence from sandbox/staging instead of production
|
|
266
|
+
- Manually edit evidence after collection (auditors may verify against source)
|
|
267
|
+
- Wait until the week before the audit to collect everything
|
|
268
|
+
- Assume stale evidence is acceptable — check freshness requirements above
|
|
269
|
+
- Mix evidence from different audit periods in the same file
|
|
270
|
+
|
|
271
|
+
## Troubleshooting
|
|
272
|
+
|
|
273
|
+
| Problem | Solution |
|
|
274
|
+
|---------|----------|
|
|
275
|
+
| API command requires auth | Use existing local credentials: `gcloud auth login`, `az login`, `gh auth login` |
|
|
276
|
+
| Tool not installed | Install: `brew install gh`, `brew install --cask google-cloud-sdk`, `brew install azure-cli` |
|
|
277
|
+
| Insufficient permissions | Request read-only access to the relevant service; document the access request as evidence |
|
|
278
|
+
| Evidence too large | Use `--limit` or `--max-events` flags; collect summary statistics instead of full export |
|
|
279
|
+
| Vendor won't provide SOC 2 report | Request via their trust center; if unavailable, document the request and use their security page |
|
|
280
|
+
| Screenshot doesn't include clock | On macOS: use full-screen capture, or `screencapture -x` which includes menu bar |
|
|
281
|
+
|
|
282
|
+
## Rules
|
|
283
|
+
|
|
284
|
+
For detailed evidence collection guidance by topic:
|
|
285
|
+
|
|
286
|
+
| File | Coverage |
|
|
287
|
+
|------|----------|
|
|
288
|
+
| `rules/api-exports.md` | CLI commands by cloud provider (GCP, Azure, AWS, GitHub, Google Workspace) |
|
|
289
|
+
| `rules/screenshot-guide.md` | When and how to take audit-ready screenshots |
|
|
290
|
+
| `rules/evidence-types.md` | Evidence type requirements per control domain |
|
|
291
|
+
|
|
292
|
+
## Attribution
|
|
293
|
+
|
|
294
|
+
Evidence collection procedures and control guidance developed with [Internal ISO Audit](https://internalisoaudit.com) (Hazel Castro, ISO 27001 Lead Auditor, 14+ years, 100+ audits).
|
|
295
|
+
|
|
296
|
+
## Runtime Detection
|
|
297
|
+
|
|
298
|
+
1. **Compliance MCP server available** (best) — Automated gap detection, evidence freshness tracking
|
|
299
|
+
2. **Local compliance data available** (good) — Reads evidence status from `compliance/evidence/*.md`
|
|
300
|
+
3. **Reference only** (baseline) — Uses embedded checklists and command reference
|