Skip to content
cccskills
FreePublished on GitHub

compliance

Manage the recorded list of vendors that process customer data and check advance notices and audit evidence. The skill also explains temporary staff access to customer accounts, including access limits, revocation, and the actions recorded in customer audit logs.

OriginalShow the original description

Customer-facing compliance duties that code runs: the subprocessor list and its automatic 30-day DPA notice, and the audit evidence it leaves. Load WHENEVER you add, remove or change a subprocessor (a new model provider, host, email or analytics vendor), route customer data to a new third party, touch apps/web/.../legal/subprocessors, packages/shared/src/subprocessors.ts or apps/api/src/billing/services/subprocessor-notices.ts, or need proof for an auditor that customers were notified. Load too for staff access to a customer account: act-as impersonation, 'Open as admin', and its audit trail; and for a penetration test report: the status of each finding and the risks Kortix accepts.

Works withSupabase
See how to install

Good for

  • Adding a vendor that processes customer data
  • Checking notice timing before sending data to a new vendor
  • Retrieving notification evidence for an auditor
  • Reviewing staff access grants and customer audit logs

Files included (2)

  • SKILL.md7.2 KB
  • references/supabase-legacy-key-retirement.md3.5 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Compliance

The Data Processing Addendum (DPA) promises two things that code keeps:

  • Section 7.2 / Annex III: /legal/subprocessors lists every third party that processes customer personal data.
  • Section 7.3: a new subprocessor gets at least 30 days' notice before it processes customer personal data.

Add a subprocessor

A new vendor that sees customer data is a subprocessor: a model provider for Kortix-managed models, a host, an email, log or analytics vendor. A model a customer reaches with their own key is not one.

  1. Sign or accept the vendor's DPA. For an inference vendor, confirm zero data retention for our account.
  2. Add the row to packages/shared/src/subprocessors.ts. Use the vendor's legal entity name from its terms. Set addedOn to the day the PR merges. Move SUBPROCESSORS_UPDATED to the same day.
  3. Merge to dev. The row ships with the next prod release.
  4. Send the vendor no customer data before the row's effective date (addedOn + 37 days). The page shows it as "From <date>". Managed-model inference is served by Platinum Inference: give the Platinum team the same date, and Platinum Inference holds the change back until then.

A change to an existing row (purpose, location) needs no addedOn and sends no email. Removing a vendor needs no notice: delete the row.

What runs by itself

runSubprocessorNoticeSweep (apps/api/src/billing/services/subprocessor-notices.ts) runs hourly in the billing worker, on prod only (INTERNAL_KORTIX_ENV=prod).

  • A row is open from the first sweep that sees it on prod until its effective date. The release has 7 days to reach prod, so every customer gets 30 to 37 days.
  • Each open notice goes once to the owners and admins of every paid account (credit_accounts.tier not free or none). Reply-To is privacy@kortix.com: a reply is an objection.
  • Each notified account gets an audit event legal.subprocessor_notice.sent (resource_id = addedOn, output_summary = recipient count, effective date, vendor names). The customer sees it in the account's audit log.
  • privacy@kortix.com gets one report per sweep that sent. Subject "Subprocessor notice gave only N days" means the release took more than 7 days: hold the vendor until 30 days after that report and move addedOn.

Evidence for an auditor

select account_id, created_at, output_summary
from kortix.audit_events
where action = 'legal.subprocessor_notice.sent' and resource_id = '<addedOn>'
order by created_at;

The privacy@kortix.com reports give the per-sweep totals.

Tests

apps/api/src/__tests__/integration-subprocessor-notices.test.ts: pnpm test -- --db-only integration-subprocessor-notices.

Staff access to a customer account (act-as)

A platform admin enters a customer account only through an act-as grant (kortix.impersonation_grants, apps/api/src/shared/impersonation.ts). There is no other door: the read-only x-kortix-admin-bypass header was retired on 2026-10-19 and the API ignores it.

  • Two entry points, one grant: Admin → Accounts → Open as account ({account_id}), and "Open as admin" on a project's access screen ({project_id}; the API resolves the project's account).
  • A grant lives at most 1 hour. The web app shows a banner while it is live. Exit revokes it. A new grant revokes the one it replaces.
  • Inside the grant the operator acts as the account owner and holds session oversight: a member's private session opens. Routes that create access outliving the grant (tokens, members, SSO, shares, connections) answer 403.
  • The customer's audit log records admin.impersonate.start, .stop, one admin.impersonate.action per write, and project.admin_oversight_session_read the first time each private session opens in an hour (per API task).
select created_at, action, actor_user_id, metadata
from kortix.audit_events
where account_id = '<account_id>' and action like 'admin.impersonate.%'
order by created_at desc;

Contract: flows IMP-1 and IMP-2 (pnpm test -- --id IMP-2).

Penetration test findings

The register of third-party pentest findings. One row per finding, with its status and the evidence. An accepted risk names the reason and the control that limits it. The report itself stays out of the repository: it holds tokens and account ids.

Web app pentest, July 2026 (scope: dev.kortix.com, dev-api.kortix.com)

#FindingStatusEvidence
1BOLA: GET /v1/billing/account-state returned the billing state on membership alone (Medium, CVSS 5.3)Fixed 2026-10-21The route returns the money fields only when authorize grants billing.read. Every other caller gets the gating view (can_run, plan, entitlements). Flow BILL-21. Since 2026-08-19 every built-in account role holds billing.read, so a plain member reading the state is intended.
2Account name accepts HTML (Informational)Fixed 2026-10-21accountNameError refuses <, > and control characters on create and rename. Every email template escapes the name (escapeHtml). Flow ACCT-4.
3JWTs signed with HS256 (Informational)Staging fixed 2026-10-21; prod after the next releaseEvery hosted project signs user tokens with ES256 since 2026-08-21. 2026-10-21: dev, staging and prod moved to sb_publishable_ / sb_secret_ keys with zero downtime (325 probe checks, 0 failures), and the API stopped trusting the legacy secret itself (random SUPABASE_JWT_SECRET in every hosted env). Staging: legacy API keys disabled and the HS256 secret revoked; a token forged with the old secret for a real session gets 403 from Supabase and 401 from the API. Prod and dev wait for the mobile app to ship the publishable key. Procedure: references/supabase-legacy-key-retirement.md.
4Concurrent logins allowed (Informational)AcceptedUsers run the web app, desktop, CLI and mobile at once; a one-session rule breaks that. Controls: account MFA enforcement, SSO enforcement, admins list and revoke any member session (GET /v1/accounts/:accountId/iam/sessions, POST …/iam/sessions/:sessionId/revoke).
5Session cookie without Secure (Informational)Fixedapps/web/src/lib/supabase/client.ts and server.ts set Secure on HTTPS. HSTS is on at the edge.
6Session cookie without HttpOnly (Informational)AcceptedThe Supabase browser client reads the session from JavaScript (client.ts comment). Controls: React output encoding, server-side input validation (#2), SameSite=Lax, short-lived access tokens. Removing it means a server-only session, a separate project.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

access-policy

FreeSummary

Review Slack access requests against Okta role and team information, then prepare narrowly scoped GitHub or AWS IAM permissions. Apply changes only after an eligible person's approval and record the grant, reasoning, approver, and timestamp.

  • Reviewing GitHub repository access requests from Slack
  • Preparing AWS IAM permissions for a specific task
  • Routing sensitive access requests for additional review
kortix-ai/suna20.3KUpdated Oct 22, 2026

account-research

FreeSummary

Research companies and people before outreach or meetings. Combines business profiles, recent news, hiring signals, and key contacts into a sourced brief with talking points and suggested questions, adding relationship history when CRM data is connected.

  • Research a prospective customer before outreach
  • Prepare background information for meeting attendees
  • Compare a competitor's products and positioning
kortix-ai/suna20.3KUpdated Oct 22, 2026

Review daily Google Ads and Meta Ads results for budget pacing, declining performance, and unusual activity. Get prioritized findings with supporting numbers and concrete recommendations for a marketing team to assess and carry out.

  • Checking whether campaign budgets are being spent on schedule
  • Investigating rising acquisition costs or falling ad returns
  • Finding ads and keywords that spend without converting
kortix-ai/suna20.3KUpdated Oct 22, 2026

agent-browser

FreeSummary

Automate website tasks such as navigating pages, filling forms, clicking buttons, taking screenshots, and extracting data. The skill also supports web app testing, with specialized guides for Electron desktop apps, Slack, and cloud browsers.

  • Automate form entry and page navigation
  • Capture screenshots and extract page data
  • Explore web apps for bugs
kortix-ai/suna20.3KUpdated Oct 22, 2026

ap-invoice-match

FreeSummary

Process emailed vendor invoices by extracting details, comparing them with purchase orders and invoice history, and recording duplicates, overcharges, or missing orders. Summarize results in Slack for human review; payment approval and execution remain with people.

  • Checking incoming invoices against purchase orders
  • Finding duplicate invoices and likely resends
  • Reviewing unit prices and remaining order balances
kortix-ai/suna20.3KUpdated Oct 22, 2026

billing

FreeSummary

Guide changes to Kortix billing code, admin controls, and pricing screens. Explain how plans, trials, enterprise contracts, and access exceptions should work, where pricing is defined, and which audited routes must handle account changes.

  • Update billing logic and its specification together
  • Review how trials and enterprise contracts are handled
  • Find the code that defines prices and allowances
kortix-ai/suna20.3KUpdated Oct 22, 2026

See all skills by kortix-ai

Report a problem with this skill