Sécurité et confiance

Badgeye n'a pas de rapport SOC 2 et n'a pas fait l'objet d'un test d'intrusion par un tiers. Voici ce que le logiciel fait aujourd'hui et ce qu'il ne fait pas.

Ce qu'il fait aujourd'hui

  • L'agent tourne sur votre poste et ne fait que des connexions sortantes.
  • Les mots de passe sont saisis par le coffre Blindfold et gardés hors des invites, journaux et enregistrements (tests de fuite en CI).
  • Une barrière de sortie du navigateur refuse les adresses privées et internes.
  • Des règles d'injection d'invite et de fraude filtrent courriels et pages; un paiement signalé exige toujours une personne.
  • Le journal d'audit est en ajout seulement, chaîné par empreintes, et exportable avec une signature vérifiable hors ligne.
  • Rôles, connexion en deux étapes et authentification unique OIDC pour la console.
  • Le texte saisi est capté avec consentement et masqué sur le poste avant de partir : noms, numéros et secrets sont retirés. Les champs de mot de passe, sécurisés et de code à usage unique, les fenêtres privées et la captation en pause ne produisent rien.
  • Modes d'identité : identifié, pseudonyme (par défaut) ou anonyme, avec un seuil d'au moins 5 personnes avant qu'un rôle ou une équipe affiche quoi que ce soit.

Pas encore

  • Aucun rapport SOC 2 ni autre audit
  • Aucun test d'intrusion par un tiers
  • Les installateurs signés sont prévus
  • Pas encore de choix de résidence des données
  • L'envoi de courriels en production et l'examen des applications Slack et Teams sont en attente

Contrôles, associés aux critères SOC 2

Tiré de docs/SECURITY_CONTROLS.md, lu à la compilation. C'est un document d'ingénierie, pas une attestation. Il est en anglais.

1. Common criteria (security)

CritèreContrôleÉtatÉcart
CC6.1 Logical access: identification and authenticationPer-person sign-in: scrypt password hashes with per-hash salt and stored parameters, constant-time compare, equal work for unknown emails; opaque random session tokens stored only as SHA-256, expiring and revocable; roles read from the person on every requestImplémentéNo passkeys/WebAuthn (planned). No email verification at invite.
CC6.1Two-step sign-in (TOTP) with sealed seeds (AES-GCM), hashed one-time recovery codes, replay protection, org policy for owners/admins (optionally approvers), audited admin resetImplémentéNot tested against every authenticator app.
CC6.1Single sign-on with OpenID Connect (Google Workspace, Microsoft Entra, Okta, generic): authorization code + PKCE (S256), single-use state bound to the browser by an HttpOnly cookie, nonce, issuer/audience/expiry/not-before checks, signature against the issuer's JWKS (asymmetric algorithms only, none/HMAC refused, key type must fit the algorithm), JWKS cache with rotation and a refetch cooldown, per-org email-domain allowlist, verified email required, linking only to people already invited (or auto-create if an owner switches it on, never as owner), subject-based identity after the first link, optional group-to-role mapping (approver/admin only), owner can require SSO with a named break-glass ownerImplémentéNot run against a real Google/Entra/Okta tenant. Domain ownership is not verified (two orgs claiming one domain makes SSO ambiguous and is refused, but the first claim is trusted). No SCIM provisioning or deprovisioning: removing someone at the IdP does not end an existing Badgeye session before it expires (session_hours). Microsoft sends no email_verified; the tenant-specific issuer is the control.
CC6.1Brute-force defence: exponential backoff per email + IP pair, per-IP cap, stored in the database so every serverless instance agrees; the limit cannot be used to test guesses; SSO start and callback are rate limited per IPImplémenté
CC6.2 Registration and removal of usersInvite by an owner/admin creates a person with a one-time temporary password that must be changed; only an owner can add an owner; MFA reset by an owner/admin is auditedImplémentéNo user deprovisioning API or console action beyond ending sessions (planned). No periodic access review tooling (organizational + planned).
CC6.3 Role-based access, least privilege, segregation of dutiesRoles owner/approver/admin enforced in the API; the real signed-in person (not a picker) approves; the service token is for machines and refused from browsers; org-scoped queries; SSO settings are owner-only; signed audit export is owner/admin-onlyImplémentéRoles are coarse (three). Fine-grained permissions planned.
CC6.1, CC6.6Secrets never reach the model or logs: Blindfold vault with AES-256-GCM, decrypt only inside the fill, redaction of recordings/logs/model requests, fingerprint scan before anything leaves the agent; SSO client secrets and the audit signing key are sealed with AES-GCM under a key derived from BADGEYE_AUTH_SECRETImplémentéBADGEYE_AUTH_SECRET lives in the environment, not an HSM/KMS (planned). Changing it makes sealed values unreadable (re-enter the SSO secret; audit key: see below).
CC6.6 Boundary protectionBrowser egress gate (public http(s) only, DNS answers checked, per-task site pin); agent is outbound-only; OIDC discovery/JWKS/token fetches refuse non-https and (in production) non-public addresses, no redirects, 1 MB cap, 5 s timeoutImplémentéDNS rebinding between the SSO address check and the connection is not closed. Run behind an egress firewall for strong guarantees.
CC6.7 Transmission and movement of dataTLS on the hosted control plane (platform); session cookie HttpOnly, SameSite=Lax, Secure in production; zero secrets on the agent-cloud wirePartielAgent mTLS and certificate rotation planned. Transport security of the hosting platform is theirs.
CC6.8 Prevention of unauthorized softwareSkill versions are immutable and promoted only on a 100% replay; signed installersPartielSigned installers are planned (roadmap gap 2).
CC7.1 Detection of vulnerabilities / configuration changesEgress/injection eval set, leak tests in CI; dependency licence reviewPartielNo automated dependency vulnerability scanning in CI, no third-party penetration test (planned).
CC7.2 Monitoring for anomaliesEvery action, sign-in, failed sign-in, SSO failure with reason, MFA reset, settings change and export is an audit row; SIEM exportImplémentéNo built-in alerting rules; SIEM is the route (customer-run).
CC7.2, CC7.3 Tamper-evident recordAudit log is append-only (ORM guard + SQLite/Postgres triggers, including TRUNCATE on Postgres) and hash-chained per org; GET /v1/audit/verify recomputes the chain. Signed export: a date range as JSONL + CSV with a manifest signed with the org's Ed25519 key; badgeye audit verify <export> checks signature, every hash, every link, the CSV against the JSONL and the anchors offline (no database, no network) and names the first bad row; altering, deleting, inserting or reordering any row fails. Daily anchor: the chain head is recorded and signed once a day (scheduler job at 00:10 local, and on demand), shown on the Audit page and carried in exportsImplémentéThe signing key lives with the service: an attacker who controls both the database and BADGEYE_AUTH_SECRET could re-sign a rewritten history. The defence is to pin the public key and keep exported anchors/heads outside the system (customer copies, SIEM). Key rotation and external timestamping (RFC 3161 or a public transparency log) are planned. A date range is exported as the contiguous run of rows from the first to the last row dated in the range.
CC7.4 Incident responseKill switch per org/employee; operator command to switch off SSO (badgeye sso disable --org); MFA resetPartielWritten incident-response plan and on-call are organizational.
CC8.1 Change managementVersioned database migrations (Alembic, verified against the models in tests), CI suite on SQLite and Postgres, immutable skill versions with replay-gated promotionPartielCode-review and branch-protection policy is organizational.
CC9.2 Vendor and business-partner riskModel providers are the customer's own plans; documented licencesPartielSubprocessor list and vendor reviews are organizational.
CC6.1, CC7.2 Initiator on every audit rowEvery audit row records initiator_kind (person, watcher, schedule, director, handoff, outside_input, system) and initiator_id, set once where the work starts (scheduler job, watcher event, delegated task, person) and carried in a context the model cannot change; both fields are part of the row hash for new rows, older rows keep their original hash input so existing chains and exports still verify; the Audit page and GET /v1/audit/events?nobody_watching=true list work no person startedImplémentéConsole-click and API calls by a person take the person from the actor; wiring the signed-in person into every request scope is left to the API layer. Durable outbox redelivery loses the ambient initiator and records system.
CC7.2 Audit-firstAn action.attempted row is committed before any executor runs; if it cannot be written the action is not executedImplémentéInstalled by the policy module's wiring on the team service.
CC6.1, CC6.3, PI1.2 Rule policyDeny-before-allow rules over website, button label, command/tool, initiator, department and amount; layers org, department, AI employee, person; the strictest effect wins; locked team rules cannot be edited or loosened by members; a malformed rule or a failed evaluation refuses; evaluated before the limits engine and can only tighten it (never lifts a limit, approval, NEVER_TYPES or human gate); every refusal is audited with the rule id; Preview shows which rule would decideImplémentéFacts other than action type, system and amount (website, label, tool, command, department) come from the action payload and are only as good as the code that fills them.
PI1.2 Auto-review (hook)A second-opinion hook for in-limit writes that can only escalate to approval; failure, timeout or an unreadable answer counts as askImplémentéNo reviewer model is connected by default.
CC6.1, C1.1 Postgres row-level securityRLS policies on every org-scoped table keyed on current_setting('app.org_id'), a non-owner badgeye_app role without BYPASSRLS, set_config(..., true) (SET LOCAL) per transaction so it is safe behind the Supabase transaction pooler; no setting means no rows; cross-org reads, updates, deletes and inserts fail; run_as_system is the named scope for sweepsPartielOff until the deployment connects as badgeye_app (set its password and URL); the request layer must call bind_org(session, org_id); tables added by later migrations need apply_rls again; SQLite has no RLS.

2. Availability

CritèreContrôleÉtatÉcart
A1.1 CapacityServerless control plane (Vercel + Supabase); long-poll caps; per-run and per-goal caps on the agentPartielNo capacity monitoring or load testing (planned).
A1.2 Backup and recoverySupabase platform backups; schema in migrationsPartielRestore drills and RPO/RTO targets are organizational; none run yet.
A1.3 Recovery testingPrévu

3. Confidentiality

CritèreContrôleÉtatÉcart
C1.1 Identify and protect confidential informationBlindfold, redaction at every boundary, leak scans of the database, wire, recordings, audit export and API answersImplémentéData classification policy is organizational.
C1.2 Disposal30-day purge of recording frames; sessions revoked on logout/password changePartielNo customer-initiated erase of an org's data (planned). The audit log is append-only by design; export before offboarding.

4. Processing integrity

CritèreContrôleÉtatÉcart
PI1.1-PI1.5Limits by amount/action/system, shadow mode, lead review before writes, human approval gates, replay of every action, hard fraud rules, reversalImplémentéReliability against real sandbox ERPs and portals is roadmap gap 1.

5. Privacy

CritèreContrôleÉtatÉcart
P1-P8Opt-in recorder with field redaction and allow/deny lists; secrets never stored in recordingsPartielPrivacy notice, DSAR handling, retention schedule and DPA are organizational.

Pour signaler une vulnérabilité ou obtenir le document complet des contrôles, demandez l'accès et mentionnez-le.

Voir ce qui fonctionne aujourd'hui →