# Data Handling

Before adopting Bumpkit you need to know what code and data it sees and keeps; this page explains it and the controls you have, for security, privacy and legal reviewers.

This page describes what leaves your machine when you use Bumpkit, what Bumpkit stores, and the controls you have over it.

## What you send to Bumpkit

| Client | What it sends |
|---|---|
| CLI (`bumpkit gate`, `bumpkit check`) and MCP server with a local path | The output of `git diff <base> <head>` (cut at 8 MB), each commit's short hash, author name, timestamp and message, and the `origin` remote URL |
| API or MCP with only a `repository` | Nothing but the repository and refs; the Bumpkit API fetches the comparison from GitHub with its own token |
| Changelog generation (`POST /v1/analyze`, GitHub Actions) | Commit messages, with optional author, timestamp and hash, and the repository URL |

Requests are authenticated with your API key in the `x-api-key` header. The API rejects release check requests larger than 10 MB.

## What is sent to the AI provider

Bumpkit's own checks decide the release verdict. The AI provider only adds explanations, and its findings are marked `inference`. For a release check it receives:

- The first line of recent commit messages
- The title, severity and file of each finding
- A limited excerpt of the diff

When a release is very large, Bumpkit sends less, or skips the AI step, and the summary says it covers only part of the release. Blocking decisions never use AI: the verdict and every gate failure come from Bumpkit's own checks.

Checks sent with `fast: true` skip the AI step; `bumpkit gate --hotfix` (or running on a hotfix branch) sends them that way. A raw `POST /v1/gate` with `hotfix: true` and no `fast` still uses it. Changelog generation sends commit messages. Plain-English rules (Beta) send the rule text, and release docs send the engineering notes generated for the release.

## What Bumpkit stores

By default, Bumpkit keeps the results it produces, not your source tree. It never stores the diff you send. Per check it stores:

| Data | Contents |
|---|---|
| Release check | Refs, commit SHA, verdict, version bump, counts, agents, the AI summary and reasoning, and the changelog |
| Findings | Checker, kind, severity, file, lines, title, a hashed fingerprint, the detail and the code snippet that proves it |
| Changed files | Path, status and line counts of each changed file; never the contents |
| AI usage | Provider, model, input and output token counts and the number of AI calls |
| Gate decision | Outcome, rules applied, approvals, each rule's message and the `bumpkit.yml` policy |
| Release docs | Engineering notes, customer notes and migration guides |
| Request log | Endpoint, status, timing, commit count, and the generated changelog |

Bumpkit also stores what you create: codebase memories, incidents, deployments, finding feedback, gate overrides, policy rules, changelog entries and the audit log.

## Credentials and secrets

| Data | How it's stored |
|---|---|
| API keys | Hashed; the key is shown once |
| Passwords | Hashed with a slow password hash |
| Sessions | Signed cookies |
| Signed-in marker | A `bk_signed_in=1` cookie with no account details, so the site and docs show a Dashboard button |
| Invitation tokens | Hashed; the raw token is only in the emailed link |
| Password reset, sign-up and email change confirmation tokens | Hashed; each link works once |
| SCIM tokens | Hashed; the token is shown once |
| Integration and connection secrets | Encrypted at rest, see below |

### Secrets encryption at rest

Bumpkit encrypts these secrets with AES-256-GCM before storing them:

- Slack and Discord webhook URLs, the outbound webhook URL, the Linear API key and the PostHog API key
- Slack bot tokens
- Incident source and deploy source secrets
- Change management credentials (Jira, ServiceNow, Teams, Vanta, Drata) and Notion and Confluence tokens
- OIDC client secrets, when [single sign-on](/docs/sso#single-sign-on) (Beta) is configured
- [Audit streaming](/docs/compliance#audit-streaming) destination secrets
- GitLab, Bitbucket and Azure DevOps gate connection secrets and access tokens
- The workspace's evidence signing key

Bumpkit never writes these secrets in plain text, and encryption keys support rotation.

## Sign-in protection

Password sign-in is rate-limited per account and per network, and repeated failures pause sign-in for that email address for a while. Sign-up needs a confirmed email, password reset links work once and expire in 30 minutes, a new sign-in email has to be confirmed from its own mailbox, and the dashboard refuses cross-site form posts. See [Sign-in security](/docs/sso#sign-in-security).

## What Bumpkit sends to other services

| Destination | When |
|---|---|
| GitHub, GitLab, Bitbucket or Azure DevOps | To read repositories, post checks and comments, and run the GitHub App, when you connect them |
| OSV (`api.osv.dev`) | Package names and versions from dependency changes, to look up advisories |
| Slack, Discord, Linear, PostHog, outbound webhooks | Release and approval notifications you configure |
| Email provider | Invitations, alerts and notifications |
| Stripe | Billing |

## Delete a workspace

On the dashboard, the workspace owner opens **Settings → Delete workspace**, types `delete` and confirms. This permanently deletes the workspace and everything in it, including its memberships, API keys, checks and integrations. Team members keep their Bumpkit accounts and their other workspaces. From the CLI, run `bumpkit workspace delete`. It can't be undone.

## Zero retention

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `zero_retention`.

The **Data** tab on the dashboard's **Settings** page (`/settings?tab=data`) shows exactly what is stored for the workspace, how many records of each kind, where it's stored and what the AI provider receives. Any member can view it. The owner (and, with roles on, an admin) can change the settings and export the data; only the owner can delete it.

### Retention modes

| Mode | Key | What's stored |
|---|---|---|
| Standard | `standard` | Everything listed under [What Bumpkit stores](#what-bumpkit-stores) |
| Findings only | `findings_only` | Findings keep their file, lines, title and hashed fingerprint. No code, snippets, diffs, AI summaries or free text derived from code |
| Ephemeral | `ephemeral` | Checks run in memory. Only verdicts and metadata are kept: outcome, counts, refs, checker and severity per finding, and the fingerprint |

What each mode keeps:

| Data | Findings only | Ephemeral |
|---|---|---|
| Release checks | Refs, SHA, verdict, bump, counts, agents | Same |
| Findings | Checker, kind, severity, file, lines, title with code removed, fingerprint | Checker, kind, severity, fingerprint |
| Changed files | Paths, status and line counts | Not stored |
| Gate decisions | Outcome, rules and approvals; messages with code removed; no policy | Outcome, rules and approvals; no messages |
| Release docs | Not stored; generated on request | Not stored |
| Codebase memories | Saved with code blocks and diff lines removed; a memory that is all code is rejected | Refused with `409 NOT_STORED` |
| Incidents | Title, link, stack frames and suspects, evidence with code removed | Title, link and the top suspected release |
| Request logs | Endpoint, status, timing, commit count; no changelog | Same |
| Deployed changes | Paths and line ranges, without enclosing function lines | Not stored |
| Changelog entries | Stored | Not stored; `POST /v1/analyze` still returns the changelog |

Switching to a stricter mode also scrubs what is already stored to match, right away. Switching back to `standard` doesn't restore removed data.

### What the AI provider receives

In `findings_only` and `ephemeral` workspaces, release checks send no code to the AI provider, unless Bumpkit's agreement with that provider includes zero data retention. When it does, checks use AI explanations as usual.

The Data handling page shows the provider, its endpoint, whether it's marked zero retention, the inference region and whether code is sent.

### Retention windows

Set how long request logs and findings are kept, from 1 to 3650 days, or `0` to keep them until you delete them.

| Window | After it passes |
|---|---|
| Request logs | Request logs are deleted |
| Findings | Findings, changed files and release docs of older checks are deleted, and the check's summary, reasoning and changelog are cleared; the verdict is kept |

Bumpkit applies the windows automatically.

### API

| Method | Path | Description |
|---|---|---|
| `GET` | `/v1/data` | Current policy, inventory and AI provider details |
| `PATCH` | `/v1/data` | Change `data_retention`, `request_log_days`, `findings_days` and/or `region` (owner or admin) |
| `GET` | `/v1/data/export` | Download the workspace export (owner or admin) |
| `POST` | `/v1/data/delete` | Delete the workspace's data (owner) |

```bash
curl -X PATCH https://bumpkit.dev/v1/data \
  -H "x-api-key: $BUMPKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"data_retention": "findings_only", "findings_days": 90}'
```

`GET /v1/data` and `PATCH /v1/data` return:

```json
{
  "data_retention": "findings_only",
  "label": "Findings only",
  "description": "Findings are kept with their file, lines and a short hashed fingerprint. ...",
  "request_log_days": 0,
  "findings_days": 90,
  "llm": {
    "provider": "anthropic",
    "endpoint": "https://api.anthropic.com",
    "zero_retention": false,
    "inference_geo": "us",
    "code_sent": false,
    "note": "..."
  },
  "stored": [
    {"name": "Release checks", "count": 412, "contains": "Refs, commit SHA, verdict, version bump, counts and agents", "code": false}
  ]
}
```

Every change is recorded in the audit log (`data.retention`, `data.windows`). From the CLI, `bumpkit data view` shows them and `bumpkit data set` changes them (`--retention`, `--request-log-days`, `--findings-days`, `--region`; `--yes` confirms changes that remove stored content).

## Export workspace data

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `zero_retention`.

The owner (or, with roles on, an admin) downloads everything stored for the workspace as one JSON file, from **Data handling → Download export**, `bumpkit data export --output FILE` or `GET /v1/data/export`:

```bash
curl -o bumpkit-workspace-export.json https://bumpkit.dev/v1/data/export \
  -H "x-api-key: $BUMPKIT_API_KEY"
```

The file has `"format": "bumpkit-workspace-export/1"`, `exported_at`, `exported_by` and one section for each kind of data: the workspace and its members, API keys, release checks with their findings, changed files, gate decisions, overrides, votes and release docs, codebase memories, incidents and their sources, deployments and their reviews, release health and error counts, finding feedback, policy rules, request logs, releases and the audit log.

Secrets and key hashes are left out: API keys appear only as prefix, label, revoked flag and dates, and incident sources omit their secrets. Each export is recorded in the audit log as `data.export`. A workspace can export 5 times per hour; beyond that the API returns `429 RATE_LIMIT_EXCEEDED` with `Retry-After: 3600`.

## Delete workspace data

> **Beta, early access.** A workspace without access gets `403 FEATURE_EARLY_ACCESS` and a link to request it. Flag: `zero_retention`.

The owner can permanently delete a workspace's data while keeping the workspace, from **Data handling → Delete data**, signed in to the dashboard, confirming with the exact workspace name. `bumpkit data delete` and the API refuse a key and say where to do it. A denial on a commit keeps holding that commit, with the person's name and email removed.

The response counts the records removed for each kind of data.

Deletion runs immediately and all at once. It removes release checks (with their findings, changed files, gate decisions and release docs), codebase memories, incidents, request logs, changelog entries, finding feedback, deployments, gate overrides, error fingerprints and counts, policy rules, gate votes, Slack approval messages, Slack pull request messages and deployment reviews. Members, API keys, settings, integrations and the audit log stay. The deletion and the counts are recorded in the audit log as `data.delete`.

To remove the workspace itself, [delete the workspace](#delete-a-workspace).
