Five frameworks, one audit trail.
Tallywyrmis a 24/7 FinOps agent for multi-cloud spend. This page maps the five frameworks named in the mission — SOC 2 Type II, ISO 27001, FedRAMP Moderate, EU CSRD and SEC climate disclosure — to the credential, encryption, access control and sub-processor surfaces that back each one.
One matrix, five frameworks, five controls.
Each cell names the artefact in this repo that backs the claim — a file the auditor can open in the same workspace as this page. The table is the same data the FAQPage JSON-LD at the bottom of the page renders.
| Framework | Read-only credential scope | Encryption | Authentication & 2FA | IaC-write boundary | Audit trail & sub-processors |
|---|---|---|---|---|---|
SOC 2 Type II Read-only cloud credential contract + weekly audit-trail CSV export backing all five trust-service criteria. | ✓ OIDC trust, scoped per workspace; no break-glass. | ✓ TLS in transit + platform-managed at rest. | ✓ requireAuth() per route; 2FA via src/lib/auth-2fa/{challenge,session,status,totp}.ts enforces TOTP on every login. | ✓ PRs only via iac-snippet-panel.tsx — no terraform apply execution surface exposed to the agent. | ✓ Weekly CSV export with who/what/when/IP rows; 13-month retention per workspace; sub-processors named below. |
ISO 27001 Annex A control families, risk treatment register, statement of applicability and supplier-relationship controls. | ✓ Supplier-relationship controls (A.15) — credentials issued by you, brokered through your OIDC trust. | ✓ A.10 cryptography bound to platform defaults + AES-256-GCM TOTP secret at rest (totp.ts). | ✓ A.9 access control: per-user scoping + requireAdmin() on admin routes; 2FA gates every authed route. | ✓ A.12.1.2 segregation of duties: agent cannot write to control-plane; PR is the only delivery surface. | ✓ A.12.4 logging + monitoring: weekly CSV export, retention windows per workspace, sub-processor list on file. |
FedRAMP Moderate Moderate baseline mapped through SOC 2 + ISO 27001, with continuous monitoring cadence and US-region data residency. | ✓ US-region OIDC trust, scoped per account; same read-only contract as SOC 2. | ✓ TLS in transit + platform-managed at rest, US-region data residency by default. | ✓ AC-2 account management via per-user scoping; IA-2 MFA enforced by the TOTP subsystem per sign-in. | ✓ CM-5 access restrictions for change management: no agent-driven direct apply inside the trust boundary. | ✓ AU-2/AU-6 audit events captured in the same weekly CSV export the SOC 2 pack uses. |
EU CSRD Double-materiality assessment inputs and the audit trail finance teams reconcile against for ESRS E1 disclosures. | ✓ Read-only scope is the ESRS E1 disclosure source: nothing the agent could read is a control-plane secret. | ✓ ESRS S3 expected confidentiality controls satisfied by TLS + platform-managed encryption at rest. | ✓ ESRS G1 governance disclosures backed by admin/analyst separation + TOTP 2FA on every login. | ✓ ESRS E1 transition plan evidence: each saving carries a PR, a deploy timestamp and a post-deploy measurement. | ✓ Double-materiality assessment inputs roll up from the weekly CSV; sub-processors listed for value-chain mapping. |
SEC climate disclosure Scope 1/2/3 disclosure inputs from the audit trail, ready for the SEC climate rule attestation. | ✓ Scope 3 cat. 1 reporting starts from the read-only inventory; the boundary is auditable from a single source. | ✓ Same encryption posture; no claim of customer-controlled KMS. | ✓ ICFR attestation support: admin/operator actions gated by requireAdmin(), audit-team reads scoped by requireAuth(). | ✓ Each disclosed saving is reproducible from the PR + the audit row; no off-ledger direct applies. | ✓ Same weekly CSV export populates the SEC metric-and-target disclosures as the SOC 2 trust-service-criteria report. |
Each cell points at a concrete artefact in this repo — file names referenced above are stable across deploys. Cell copy is regenerated by hand from the same source-of-truth constant that powers the FAQPage JSON-LD below; if you rename a referenced file, update FRAMEWORK_MATRIX here and the matching acceptedAnswer.text in lock-step.
The credential contract and the audit-trail export, together.
Same wording as /security and /privacy. The credential we ask for is the smallest one that produces a useful saving; the export is the artifact every framework above already requires.
- Read-only scope against the granted accounts — same wording on /privacy and in the FAQ.
- Brokered through your existing OIDC trust, never long-lived static keys.
- No write surface — cannot write to billing APIs, IAM, identity, or any control-plane service.
- No organisation-admin or account break-glass role, no role escalation, no cross-account assume-role into resources you have not already federated.
In transit and at rest, on the same platform defaults.
No customer-controlled KMS posture is claimed here. Encryption relies on the platform defaults every Polsia app inherits.
- TLS termination at the platform edge, applied uniformly to the app, the object store and the outbound webhook calls.
- No plaintext credential transmission — inventory and audit requests use the OIDC-mediated short-lived tokens the credential contract on /privacy binds to.
- Platform-managed encryption at rest for the database, with the same retention window /privacy publishes.
- Platform-managed encryption at rest for the object store that holds report artifacts and audit exports.
Four layers, one access model.
Authentication & 2FA, the admin-vs-analyst role boundary, per-user scoping, and audit logging. No shared password, no custom admin cookie, no per-tenant bypass.
- Every authenticated route runs through the installed session library (src/lib/auth.ts); sessions are scoped per user and per workspace.
- A TOTP-enrolled user cannot reach an authed route without passing the /2fa-verify challenge — enforced by src/lib/auth-2fa/challenge.ts together with src/lib/auth-2fa/totp.ts (RFC 6238, AES-256-GCM at rest).
- Backup codes (src/lib/auth-2fa/totp.ts → BACKUP_CODE_REGEX) are scrypt-hashed at rest with a 16-byte salt and never logged in plaintext.
- 2FA subsystem errors fail open on the open-challenge path only — a broken 2FA never blocks sign-in for the user.
- Admin / operations surfaces require requireAdmin() (src/lib/require-admin.ts) on top of the per-user scoping — the better-auth admin plugin is the role source of truth.
- Per-user API routes require requireAuth() (src/lib/require-auth.ts), returning a 401 on a missing session and a 403 for a non-admin hitting an admin route.
- There is no shared password, no custom admin cookie, no hand-rolled role check. Non-admin users (analyst, operator) hit requireAuth()-gated routes; only the admin role passes requireAdmin().
- No `requireRole('analyst')` helper exists — that is the better-auth admin plugin's `admin` vs non-admin boundary, not a multi-role matrix.
- Every read and write in the app is constrained by `userId` so one tenant cannot see another tenant's inventory, audit events or weekly reports.
- Sessions are scoped per user plus per workspace; cross-workspace reads require an explicit guard in the /api handler.
- No organisation-admin role is claimed anywhere in the agent — the role model is admin vs non-admin / analyst / operator.
- Each audit row is a who/what/when/IP tuple, with the same schema the weekly CSV exporter surfaces and the FAQ describes.
- Retention is 13 months minimum, configurable per workspace — the same window that bounds the export on /privacy.
- A weekly CSV exporter ships in the dashboard under the verified-savings trend — one row per offender plus a summary header row.
Rightsizing arrives as PRs only.
The agent emits IaC snippets; your CI/CD or platform team reviews and applies. No execution surface, no control-plane write — the PR is the only delivery channel.
- No `terraform apply` execution surface is exposed to the agent. The agent emits IaC snippets; your CI/CD or platform team applies them.
- No console / IAM / control-plane write surface is exposed. The agent cannot write to billing, identity or any control-plane service.
- Every recommended saving produces a PR + a deploy timestamp + a post-deploy measurement in the same audit row — the row is the delivery unit.
- The registry itself lives in src/lib/business/iac-snippets.ts and the unused-frameworks pivot is rendered by iac-snippet-panel.tsx; neither is reachable from a write-capable code path.
Snippet registry in src/lib/business/iac-snippets.ts. The unused-frameworks pivot is rendered by the dashboard island iac-snippet-panel.tsx. Neither is reachable from a write-capable code path.
One CSV export, one audit window.
The export below is what every reconciliation framework above relies on. The named control (who/what/when/IP + 13-month retention) lives in the access-control grid above; this section is the artefact itself.
PR diff, deploy timestamp, post-deploy measurement, credit applied — one CSV, one audit window.
- Each saving ties to a diff, a PR, a deploy timestamp and a post-deploy measurement — the same attribution schema the FAQ describes.
- Audit verifications, audit diff and the report week are exported alongside the savings rows so the file is the same evidence pack finance and security teams already reconcile against.
- The retention window on /privacy is the same that bounds the export — 13 months minimum, configurable per workspace.
Frequently asked format on /faq and the retention window on /privacy.
The parties in the data path, named.
Every sub-processor that touches customer data today, with the purpose and the data category the GDPR / CSRD record demands.
| Sub-processor | Purpose | Data category |
|---|---|---|
| AWS | Hosting and multi-cloud inventory source | Inventory snapshots, audit events, weekly reports |
| Cloudflare R2 | Object storage for report artifacts and audit exports | CSV exports, diff payloads, archived audit logs |
| Stripe | Subscription and percentage-of-savings billing | Billing email, subscription state, invoice amounts |
| Email proxy | Transactional mail (alerts, contact-form submissions) | Notification payloads, contact-form content |
| Session library | Authentication and session lifecycle for authed surfaces | Session cookies, user identity claims |
A FinOps analyst reads every inbound message.
The CTA below opens the existing inbound-email form on /contact. Replies within one business day, with the latest trust-service-criteria summary attached.