Security & compliance

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.

The short version
The audit trail is the same artifact every framework already asks for.
Nothing on this page is a new attestation. It is a public mapping from the same credential contract and weekly export /security, /privacy, /terms and /faq already publish.
Frameworks & controls

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.

FrameworkRead-only credential scopeEncryptionAuthentication & 2FAIaC-write boundaryAudit 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.

Data handling

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.

Bring-your-own credential scope
The four points below match /privacy and the FAQ verbatim.
  • 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.

Full contract on /privacy and the FAQ on /faq.

Encryption

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.

In transit
All transport runs over TLS via the deploy defaults — no plaintext API surface exists in the data plane.
  • 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.
At rest
Managed by the platform Postgres + the platform object store. No claim of a customer-controlled KMS path.
  • 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.
Access control

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.

Authentication & 2FA
Sessions + TOTP, gated on every login
  • 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.
Role boundary (admin vs analyst / operator)
requireAdmin() on top of requireAuth()
  • 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.
Per-user scoping
Everything constrained by userId
  • 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.
Audit logging
Who / what / when / IP, every row
  • 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.
IaC-write boundary

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.

The PR is the delivery unit
The ledger, the deploy timestamp and the post-deploy measurement travel together in one audit row.
  • 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.

Audit trail

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.

Weekly CSV export
Available from the dashboard to authenticated users — one row per offender plus a summary header row, ready for Excel or Sheets.
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.

Sub-processors

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-processorPurposeData category
AWSHosting and multi-cloud inventory sourceInventory snapshots, audit events, weekly reports
Cloudflare R2Object storage for report artifacts and audit exportsCSV exports, diff payloads, archived audit logs
StripeSubscription and percentage-of-savings billingBilling email, subscription state, invoice amounts
Email proxyTransactional mail (alerts, contact-form submissions)Notification payloads, contact-form content
Session libraryAuthentication and session lifecycle for authed surfacesSession cookies, user identity claims
Request our SOC 2 report

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.

Request our SOC 2 reportReplies within one business day.