Skip to content

Editions, organizations & BYOK

Tripwire runs in two editions from one codebase, chosen with TRIPWIRE_DEPLOYMENT_MODE:

Self-hosted (selfhosted)Cloud (cloud)
OrganizationsOne — created at first runMany — one per signup
SignupClosed (first-run setup screen)Open self-service
AI keyThe org's BYOK key, or the instance ANTHROPIC_API_KEYEach org must BYOK its own key
BillingLicense (no metered billing)License (no metered billing)

Every row of data — suites, runs, issues, plans, settings, members — is scoped to an organization, and the two are fully isolated: a user in one org can never see or touch another's. A user belongs to exactly one org.

Roles

RoleCan
ownerEverything; created automatically as the first user of an org.
adminManage members, invites, settings, the org name — same as owner for day-to-day.
memberAuthor and run suites, triage issues — not org administration.

Self-hosted first run

A fresh self-hosted instance has no users. Open the dashboard and you get a one-time "Create your admin account" screen — that creates the single org and its owner. Or pre-seed it headlessly:

ini
TRIPWIRE_DEPLOYMENT_MODE=selfhosted
TRIPWIRE_ADMIN_EMAIL=admin@yourco.com
TRIPWIRE_ADMIN_PASSWORD=change-me-now
TRIPWIRE_BASE_URL=https://tripwire.yourco.com   # used in invite links

Signup is closed; you grow the team with invites.

Cloud signup

In cloud mode, anyone can self-serve at the signup screen: email + password + organization name creates a new, isolated org with that user as its owner. Signups are rate-limited per IP. Each org then sets its own AI key (BYOK).

Inviting your team

An admin invites by email + role from Settings → Members:

  1. Invite — creates a tokenised link (/accept-invite?token=…) that uses TRIPWIRE_BASE_URL. Send it to the person (the dashboard shows it; email delivery is up to your proxy/SMTP).
  2. Accept — they open the link, see "You've been invited to {org} as {role}", set a password, and they're in — as a member of your org.

Invites expire after 7 days, are single-use, and are listed (and revocable) under Settings → Members. A person who already has a Tripwire account elsewhere can't be invited (one user → one org); use a different address.

BYOK (bring your own key)

Tripwire never pays for your AI usage — each org brings its own Anthropic key. Set it under Settings → AI (the onboarding flow prompts for it on first run). It's encrypted at rest and, critically, threaded per-run in memory — it is never written to the shared process environment, so concurrent runs of different orgs can never see each other's key. Tracker (GitHub/GitLab/Jira) and log-backend credentials work the same way: per-org, isolated.

In selfhosted mode, an org with no key falls back to the instance ANTHROPIC_API_KEY (handy for a single-tenant box). In cloud, each org must set its own.

Audit log

Every security-relevant action — logins, signups, member and invite changes, session revocations, settings edits, org renames — is recorded per org. Admins see it under Settings → Audit log (or GET /api/v1/audit). Secret values are never logged (only which keys changed).

Configuration

VariableDefaultPurpose
TRIPWIRE_DEPLOYMENT_MODEcloudcloud (open signup, many orgs) or selfhosted (one org, closed signup).
TRIPWIRE_BASE_URLdashboard originPublic URL used to build invite links. Set to your domain in prod.

The dashboard reads GET /api/v1/config (public) at startup to adapt the UI to the edition. See Settings & env and Authentication.

Running the cloud edition: the hardening gate

Data isolation and per-org BYOK make the data layer safe for multi-tenant use. The cloud edition also executes a tenant's instructions (an LLM driving a real browser) on shared infrastructure — two extra risks a single-tenant box doesn't have. Both have built-in controls; turn them on for cloud:

  1. Egress isolation (SSRF). A run fetches whatever URL the tenant points it at — including, on cloud infra, the metadata endpoint (169.254.169.254) and internal services. Set TRIPWIRE_RUN_EGRESS=restricted: outbound requests (browser navigations and server-log fetches) that resolve to loopback / link-local / metadata / private ranges are rejected, with a TRIPWIRE_RUN_EGRESS_ALLOW allowlist. It's mode-aware on purpose — self-hosted stays open so it can test internal/localhost apps.
  2. Per-run execution isolation. Set TRIPWIRE_RUN_EXECUTOR=subprocess: each run executes in a killable child process with no database access (it gets only the suite, the org's key, and an output dir), with a hard TRIPWIRE_RUN_TIMEOUT_S wall-clock kill and optional memory/CPU caps. So a tenant's run can't read another's data or run forever.

For horizontally-scaled cloud, a container / Kubernetes-Job / Fly-Machine executor (one ephemeral, network-isolated container per run) plugs in behind the same executor interface — that step is tied to your platform, but the seam and the single-host isolation above are in place. Before opening cloud to untrusted tenants, also run a load + security test on your real infrastructure.

Self-hosted (one trusted org, your own network) is unaffected and secure as shipped.

Tripwire — AI-native, self-healing E2E testing. Terms · Privacy · Legal Notice