At a glance#
- Draft pull requests
- Only on its own
agent/branches. A person merges. - Writes off
- In a new workspace, every run is a dry run until you turn writes on.
- No keys in the sandbox
- A credential proxy adds them to model calls; the sandbox has no route to nightlab’s own secrets.
- Row-level security
- The database itself (Postgres) keeps each workspace’s rows apart.
- Encrypted throughout
- TLS 1.2 or later in transit; AES-256-GCM for every stored credential, under a key of the workspace’s own.
- Your region
- Hosted on AWS. Each workspace’s data stays in its region.
- No training
- Your content isn’t used to train models on nightlab-billed or commercial accounts.
- 48 hours
- The most we take to tell you of an incident that affects your data.
The agent and its sandbox#
An agent that writes code needs a short leash: each run gets a disposable, locked-down container with one way out and no keys inside.
- A container per run
- The agent works in a disposable container with no privileges and limits on CPU, memory, processes and time. Only nightlab’s sandbox can start containers, and only from images it has approved and pinned.
- One way out
- The container’s only route to the internet is a proxy that allows your code hosts and the package registries your stack needs, and refuses everything else, private addresses included. It can’t reach the model provider directly, nightlab’s own servers or cloud credentials.
- No keys inside
- No account token or model key enters the container. The repository token is used once, to clone, then removed. Model calls go through a credential proxy that swaps a short-lived per-run key for the real one, on model calls only.
- Leaks fail the run
- If a credential the run holds turns up in its diff, file names or commit messages, the run stops. New
.envfiles and private keys are refused. Credentials are masked out of the live feed and run records before they’re stored. - Your checks, offline
- Your static analysis and tests run on the change with no internet access. Live previews and screenshots use seeded sample data and throwaway logins, never yours.
- Instructions stay data
- Review comments, answers and tool output reach the model as marked data, never as its instructions. A learning from a past run takes effect only once a person accepts it.
Your repository and tracker#
nightlab pushes only to its own branches, opens only draft pull requests, and writes nothing until you turn writes on.
- GitHub App permissions
- Contents and Pull requests (read and write) to push its branches and open drafts; Checks (read and write) for its review check; Administration and Commit statuses (read) to tell you whether a branch is protected; Members (read, organisation) to confirm an owner installed it. Each installation token lasts an hour.
- Its own branches
- It pushes only under
agent/, enforced in code, never force-pushes, and leaves alone a branch someone else has committed to. We check your branch protection and show you what isn’t protected. - Drafts, and you merge
- It opens draft pull requests only. It merges only when you say so; today, a person merges, on your git host. Its reviews of your team’s pull requests are comments, never approvals.
- Writes off, to start
- A new workspace makes no pull request, comment or push until you turn writes on. That change is recorded in the audit log.
- Jira versions and fix versions
- nightlab creates, dates and releases a version when an admin asks, and sets an issue’s fix version when someone asks or accepts its suggestion, or on its own if a project chooses Automatic. Each goes through the project’s Jira connection, needs writes on, and is in the audit log. It never releases a version that still has unresolved issues unless you say where they move.
- Your tracker, as each person sees it
- Each person links their own Atlassian account, read-only, and sees only the issues it can see; issues under a security level they can’t see are hidden, and with no fresh link everything is. Starting a run checks that one issue with their own access.
AI models and your data#
nightlab doesn’t train models on your content, and each workspace chooses whose account runs its models.
- No training on your content
- nightlab doesn’t train models on customer content. On nightlab-billed models and on commercial accounts (an API key, or a Claude Team or Enterprise plan), the provider’s terms don’t let it train on your content either.
- Whose account
- Each workspace chooses: models billed by nightlab, or its own API key. A person may also connect their own personal subscription, for their own runs only; that’s their choice and their responsibility under the provider’s terms, and nightlab warns them that a personal plan may be used for training.
- What the provider keeps
- Code and tickets go to the model provider your workspace uses, under that provider’s terms. Anthropic’s API, for example, deletes inputs and outputs within 30 days, and may keep content flagged for safety review for up to 2 years. Where nightlab’s own models process your data is in the next section.
- Search stays here
- The search index behind learnings and duplicate checks is computed on our own servers, with an open model, and used only within its project.
Where your data is processed#
Your data is stored in your workspace’s region. nightlab’s own models run on Anthropic’s API today; processing them in your region, through Amazon Bedrock, is coming.
- nightlab’s models today
- nightlab-billed models run on Anthropic’s API, in Anthropic’s regions. Running them on Claude through Amazon Bedrock, in your workspace’s region for every action by default, is coming.
- You choose, per action
- A workspace admin can let a single action use a model that processes outside the region, for example a newer model for planning only. nightlab asks them to confirm the first time, records who changed it and when, and shows on the Settings page which actions leave the region, naming where each model processes: a country, an area such as the EU, Global, or Unknown.
- Enforced on every call
- If an action is kept in the region, nightlab refuses a model outside it, both when settings are saved and on every model call.
- Stored data stays put
- Runs, issues, notes and secrets are stored in your workspace’s region, whichever model processes them.
- Your own key
- With your own model provider’s key, that provider processes your prompts under its own terms and regions.
Workspaces kept apart#
The database itself keeps each workspace’s rows apart, so a bug in our code can’t show one workspace another’s data.
- Every workspace’s rows carry its id, and Postgres row-level security shows a connection only its own workspace’s rows.
- The app connects as a role that owns nothing, so a forgotten filter in our code returns nothing rather than another workspace’s data.
- Tests call every route as one workspace with another’s ids.
- People and sign-in live in a separate directory database.
- Each workspace’s tools for the agent (MCP) are named for it alone.
Encryption#
Everything is encrypted in transit and at rest, and the credentials you store are sealed again under a key of your workspace’s own.
| What | How it’s protected |
|---|---|
| In transit | TLS 1.2 or later on every hop: from your browser to our network edge, from the edge to our servers, and from our servers to the database, each with the certificate verified. HSTS for a year, subdomains included. |
| At rest | The database, its backups and our servers’ disks are encrypted with keys held in AWS KMS. |
| Your credentials | Connection secrets, model keys and Atlassian tokens are sealed again with AES-256-GCM, bound to their workspace, table, row and field, under a data key wrapped by a KMS key of the workspace’s own. A copy of the database alone opens none of them, and each key’s use is logged by AWS. |
| Sign-in secrets | Sign-in links and session tokens are random 256-bit values stored only as hashes. Second-factor secrets are sealed; recovery codes are stored as keyed hashes. |
Sign-in and access#
Sign-in is invite-only with one-time links, every route checks a role, and every change is in the audit log.
- Invite-only, no passwords
- A person signs in with a one-time email link that works once, for 15 minutes. Nobody can sign themselves up. Every address gets the same answer at the same speed, and requests are rate-limited.
- Second factors
- Workspace admins can add a passkey or an authenticator app, with ten recovery codes. nightlab’s own platform admins sign in with a passkey only, proved again every 12 hours.
- Roles
- Viewer, operator and admin, for a project or the whole workspace. Every route in the API declares the role it needs, and a test fails if one doesn’t.
- Sessions
- HttpOnly, Secure cookies, ended after 24 hours idle or 7 days, rotated every 15 minutes, with CSRF protection. “Sign out everywhere” ends every session at once, and removing a person ends theirs.
- Audit log
- Every change records who made it, when, and what it was (never the request’s contents), and sign-ins are recorded too. Admins read it in the portal. It’s kept for 2 years.
- Our own access
- Our servers have no open SSH: operators reach them through an identity-checked session, and every session is logged. Our platform admin shows workspaces and plans, never a workspace’s runs, code or people.
Hosting#
nightlab runs on AWS, in an account of its own, and each workspace’s data stays in its region.
- Region
- Each workspace’s data stays in its region (see Where your data is processed).
- Network
- The database isn’t reachable from the internet, and our servers accept traffic only through our network edge.
- Previews
- Live previews of agent-written apps run on a separate domain, so they never share cookies with nightlab.
- Backups
- The database has point-in-time recovery and 14 days of daily backups, and our servers’ disks are snapshotted daily.
How long data is kept#
Runs and the audit log are kept for 2 years, and a deleted workspace is erased 30 days later.
| Data | Kept |
|---|---|
| Runs: diffs, logs and results | 2 years after the run ends; admins can delete runs sooner |
| A run’s live feed, screenshots and mockups | 30 days after the run ends (as the workspace’s plan sets) |
| Audit log | 2 years |
| Triage verdicts | Kept while the issue is open; deleted at once if the issue is deleted in Jira or nightlab stops mirroring it; once it’s done, deleted 2 years after it was last triaged |
| A run’s suggested reviewer | With the run: 2 years after it ends |
| Our workflow engine’s record of a run | 24 hours after it ends |
| Live previews | 2 hours at most, 30 minutes idle |
| Database backups / disk snapshots | 14 days / 7 days |
| A workspace export | 7 days, encrypted under the workspace’s key; its download link lasts 15 minutes |
| A deleted workspace | Suspended at once, erased 30 days later, with its encryption key scheduled for deletion. Backups keep it for their own 14 days. |
| A person’s account | Deleted within the hour once they belong to no workspace, or on request; their name in history is replaced |
An admin can export a workspace’s data at any time: every table, its members, screenshots and mockups, but never its secrets, not even encrypted.
How we build it#
Every change is reviewed and merged by a person, and must pass the full test suite.
- Every change must pass strict type checks, linting and the full test suite, including the tests that keep workspaces apart.
- Dependencies install from lockfiles, and new releases wait 7 days before we take them.
- Container images are pinned by digest, and the scanners we run are pinned and checked against their publishers’ signatures.
- Known-malicious packages fail the build.
Incidents#
If an incident affects your data, we tell your workspace’s admins within 48 hours.
- We follow a written incident procedure: contain, preserve evidence, fix, and tell the people affected.
- We tell your workspace’s admins within 48 hours of becoming aware of it, with what we know and what we’re doing.
- We meet the notification duties of the GDPR and of Australia’s Notifiable Data Breaches scheme.
Subprocessors#
Four companies process data for nightlab, and we give at least 30 days’ notice before a change.
| Subprocessor | What it does | Where |
|---|---|---|
| Amazon Web Services | Hosting: servers, database, backups and encryption keys | Your workspace’s region |
| Anthropic | Models | Anthropic’s regions |
| Cloudflare | The network in front of nightlab | Cloudflare’s global network |
| Resend | Sign-in and invitation email | Japan |
We give at least 30 days’ notice before a change. Your own GitHub, GitLab, Jira, model provider and MCP servers are yours, connected on your instructions.
Compliance#
We build our security program on the SOC 2 and ISO 27001 frameworks, and formal certification is on our roadmap.
We’ll answer your security questionnaire in writing, and offer a Data Processing Addendum that covers the GDPR and the UK GDPR. Ask in your access request, or at security@nightlab.io.
Report a vulnerability#
Write to security@nightlab.io; we acknowledge a report within 3 business days.
Write with what you found, how to reproduce it, and what it could reach. We’ll acknowledge it within 3 business days and keep you told as we fix it.
- In scope: nightlab.io, the portal and its sign-in pages, the API, and live previews.
- Please don’t access or change other customers’ data, degrade the service, or use social engineering. Test against a workspace of your own.
- Safe harbor: if you follow this policy in good faith, we won’t pursue legal action against you, and we’ll work with you on disclosure once it’s fixed.
Machine-readable: /.well-known/security.txt. There’s no paid bug bounty yet.