Trust home
Security & Signing
Every artifact FrootAI publishes carries a verifiable signature. This page is the canonical inventory of how each surface is signed, where the signing material lives, and the exact commands to verify a download yourself.
Signing inventory
FrootAI prefers keyless signing wherever the publishing surface supports it — there is no long-lived private key for npm, PyPI, or cosign-signed artifacts. The only persistent signing key is the GPG key used for Linux distro packages, stored as GitHub Actions secrets and verifiable against the public key block below.
npm packages (`frootai-mcp`, `frootai-cli`, `frootai-sdk`)
npm provenance (Sigstore-backed)
- Where the signing material lives
- Keyless. Signed at publish time by GitHub Actions OIDC token; certificate minted by Sigstore Fulcio CA; signature logged in public Rekor transparency log.
- Verify a download
npm audit signatures frootai-mcp- Workflow / spec
- npm-publish.yml + publish-orchard-sdks.yml use `npm publish --provenance` with `permissions: id-token: write`. No long-lived key.
PyPI packages (`frootai-mcp`, `frootai-sdk`)
PyPI Trusted Publishing (PEP 740 attestations)
- Where the signing material lives
- Keyless. Uses `pypa/gh-action-pypi-publish@release/v1` with OIDC trusted-publishing — no `PYPI_TOKEN` secret. PEP 740 attestations enabled.
- Verify a download
pip download frootai-mcp --no-deps && twine check *.whl- Workflow / spec
- publish-orchard-mcp.yml + publish-orchard-sdks.yml lines ~22-24 document the trusted-publishing flow.
VS Code extension (`frootai-vscode`)
Microsoft Marketplace signature
- Where the signing material lives
- Marketplace-side. Microsoft signs the .vsix at install time once we publish via `vsce publish`. Author identity is verified via `VSCE_PAT` (Personal Access Token, GitHub repo secret).
- Verify a download
VS Code auto-verifies on install; manual verification: download .vsix from marketplace and check signature with `code --verify-extension`- Workflow / spec
- vsce-publish.yml uses `secrets.VSCE_PAT` for publish auth. The publisher account is `frootai`.
Linux .deb / .rpm packages (FrootAI CLI binaries)
GPG signature
- Where the signing material lives
- GitHub Actions repo secrets `GPG_PRIVATE_KEY_B64` + `GPG_KEY_PASSPHRASE` (private key, base64-encoded, AES-encrypted at rest in GitHub secret store). Public key + fingerprint published below.
- Verify a download
gpg --verify <pkg>.deb.asc <pkg>.deb (after importing the public key from this page)- Workflow / spec
- build-binaries.yml H8.21 step: imports the GPG key into an ephemeral GNUPGHOME, signs each binary, then `gpg --verify` self-tests before publishing.
Orchard play ZIP bundles (`cdn.frootai.dev/orchard/plays/`)
sigstore-cosign keyless OIDC + sha256 sidecar
- Where the signing material lives
- Keyless. Same model as npm provenance: GitHub Actions OIDC token → Fulcio CA → Rekor log. Each `<play>-<version>.zip` ships with `.zip.sha256` and `.zip.sigstore` sidecars.
- Verify a download
cosign verify-blob --certificate-identity-regexp '^https://github.com/frootai/' --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' --signature <play>.zip.sigstore <play>.zip- Workflow / spec
- Planned at [H7.14] (`harvest-to-play-masterplan.md`). No new key needed — extends the existing keyless OIDC pattern from npm + PyPI.
Orchard manifest.json (signature record)
Embedded sha256 + cosign signature reference
- Where the signing material lives
- Keyless (same flow as the ZIP). `manifest.json` carries `{ filename, sha256, cosign_bundle_uri }` so consumers can verify without the ZIP in hand.
- Verify a download
node -e "console.log(crypto.createHash('sha256').update(fs.readFileSync('<play>.zip')).digest('hex'))" — compare with manifest.sha256- Workflow / spec
- Planned at [H7.15] (`harvest-to-play-masterplan.md`).
MCP Federation Trust Gate
FrootAI MCP v6 acts as a universal MCP router behind one client connection, federating 21 first-party + verified-publisher MCP servers with 100 catalogued at /mcp-tooling/marketplace. Every attach passes a single, auditable trust gate — there is no silent-attach path.
Every attach resolves to one of these.
first-party-msattach without prompt · destructive ops allowedverified-publisherattach without prompt · destructive disallowedcommunityrequires explicit user prompt before attachuntrustedblocked at attach
Four checks run on every attach.
evaluate()innpm-mcp/src/federation/trust.tsruns on everyfai_attach_mcp— no bypass path.- Trust manifest is a 3-way byte-identical mirror (sha256
26565930b0c31852…) across npm-mcp, python-mcp, website. - CI gate
validate-mcp-trust-policy.jsenforces “no community/untrusted attach without override” on every PR. - Pre-release security review (8 doctrine checks) gates every release — 412 verifier checks stay green before a federation tag ships.
Every federated tool call traverses the gate before the upstream MCP is spawned. fai_invoke_via ephemeral one-shot guarantees Doctrine #7 (“handle ALWAYS detached”) — verified by the 10-test verification gauntlet that runs against the live router. Per-tenant trust overrides let your security team elevate or block any publisher in your own deployment.
Tiered identity guarantees
FrootAI composes three best-in-class identity providers — one per customer tier. We do not run our own password database, OAuth server, or MFA implementation. Each tier ships with explicit, customer-readable guarantees enforced by the doctrine documented at planning/sign-in-ecosystem.
Tier 1 — Admin access (Cloudflare Access)
Founder + on-call only · `/admin/*` routes
- Provider
- Cloudflare Access (Zero Trust) with GitHub OAuth + MFA. Identity verified at the edge before any application code runs.
- Guarantee
- Triple-defense: Cloudflare Access policy + middleware JWT verification + server-side session re-check. A bypass at any layer is detected within 60s by audit-log review.
- Roles
- 5 named roles:
admin,ops,finance,support,founder. Role catalogue atplanning/sign-in-ecosystem/rbac-role-catalogue.md.
Tier 2 — User accounts (Clerk)
Every signed-in customer · `/account`, `/api/*` routes
- Provider
- Clerk handles signup, sign-in, password reset, MFA, passwordless, social login, and session management. We never see or store plaintext passwords.
- Guarantee
- Entitlements are server-verified on every premium request. Editing
localStorage.tier = "pro"in the browser does not unlock paid features — the API returns 403. - Exit path
- Clerk's export API provides a full user JSON dump on demand. A 30-day migration path to Better-Auth or Supabase Auth is documented at
planning/sign-in-ecosystem/lock-in-escape-plan.md. No vendor lock-in.
Tier 3 — Enterprise SSO (WorkOS) · deferred
Enterprise customers with their own IdP · activates with first enterprise contract
- Provider
- WorkOS bridges your existing identity provider (Okta, Microsoft Entra ID, Azure AD, Google Workspace, OneLogin, Ping, JumpCloud, etc.) to FrootAI via SAML 2.0 + SCIM 2.0. Activates at phase
[S9]on your first enterprise contract. - Guarantee
- Your IdP remains the source of truth for who can sign in. Provisioning + deprovisioning flow through your existing SCIM directory. FrootAI never sees employee passwords.
- Bridge
- Technical bridge is WorkOS. Commercial bridge is Microsoft FastTrack onboarding for joint Microsoft + FrootAI rollouts.
Cross-tier guarantees
Apply to all three tiers
- No passwords in our code. We never see, log, or transmit plaintext credentials. Enforced by CI grep on every push (gitleaks + custom rules).
- No secrets in our repo. Every Clerk, Stripe, Cloudflare, and WorkOS key lives in Workers Secrets or GitHub Actions encrypted secrets. Public repository scanning runs on every commit.
- Audit-ready by default. Every authentication event, role change, and entitlement check writes to a tamper-evident audit log conforming to the schema at
planning/sign-in-ecosystem/audit-event.json. - Founder kill-switch. A single command from the founder laptop disables all sign-ins globally within 5 minutes during an active incident. Drilled quarterly per SOC 2 CC7.4. See
planning/sign-in-ecosystem/kill-switch-runbook.md. - Status page. Real-time per-vendor availability at account.frootai.dev/status with 90-day uptime history. (Live at phase
[S2.6].) - Compliance scope. SOC 2 Type I (in scope), GDPR (DPA executed with each identity provider), CCPA (opt-out flow documented). Stripe PCI scope: ZERO — we never touch card data.
For the data-processing roles each provider plays, see /data-protection §3.5 Authentication providers.
GPG release key
This is the FrootAI release-signing key used for Linux distro packages (`.deb`, `.rpm`) and GitHub Release artifacts. Import it once, then `gpg --verify` any signed download.
- Fingerprint
TBD — exported from build-binaries.yml run- Public key block
- frootai-release.asc
- Import + verify
curl -O https://frootai.dev/security/frootai-release.asc gpg --import frootai-release.asc gpg --verify frootai-cli_<version>_amd64.deb.asc frootai-cli_<version>_amd64.deb
First-time setup: the fingerprint + .asc file are populated by the maintainer from the live build-binaries.yml workflow output (one-time admin task). Until that happens, the fingerprint reads TBD — please fall back to npm provenance / PyPI attestations for verifiable downloads.
Secrets custody policy
- Keyless first. Every new publishing surface MUST attempt keyless OIDC (Sigstore / Fulcio + Rekor) before introducing a long-lived private key.
- Private keys are GitHub Actions repo secrets only. Never committed, never copied to local dev machines, never shared outside the CI runner.
- Rotation cadence. GPG release key: 365 days. VSCE_PAT: 90 days. NPM_TOKEN: keyless preferred (no rotation needed).
- Compromise response. Revoke key → publish revocation cert to this page → re-sign affected releases with new key → notify subscribers via GitHub Security Advisory.
Reporting a vulnerability
Use GitHub Security Advisories for any software vulnerability. For trust-and-safety reports (DMCA, license violations, harassment), use /trust instead.
Refunds — 30-day money-back guarantee
Every paid plan (Pro and Team) carries a 30-day money-back guarantee from the date of the first successful charge. If the plan isn't working for you, email [email protected] with your account email and we'll process a full refund to the original payment method within 5 business days. No justification required. After day 30, subscriptions remain cancellable at any time via /account/billing (Customer Portal) and continue serving until the end of the paid period; partial refunds for unused time outside the 30-day window are at our discretion.
Engine & Studio — Trust & Safety
FrootAI's engine disclosure and Studio sandbox introduce specific trust & safety considerations. We commit to a 48-hour SLA on initial response for all reports below.
Report to [email protected]. All categories: 48h first-response SLA. Data privacy concerns: 24h SLA.