Skip to content

Security and data handling

This page describes the security guarantees Mate provides and what data is processed during a job.

Your GitLab credentials never enter the agent container

Section titled “Your GitLab credentials never enter the agent container”

When you register a bot, you give Mate a GitLab Personal Access Token. That master token stays in Mate’s control plane — it never reaches the container where the agent runs.

For each job, Mate mints a short-lived, narrowly-scoped GitLab API key from your master token. This per-job key is:

  • Scoped to only the permissions the job’s effective authority set requires
  • Short-lived — it expires automatically about one hour after the job is dispatched
  • Stored encrypted at rest

The agent’s container holds a signed job credential (an opaque token that carries no tenant identifier) along with the GitLab base URL and the repository clone URL needed to bootstrap the run. It also briefly holds a short-lived, read-only clone token — this token is used once for the initial git clone and then zeroed from the environment immediately afterward. What never enters the container is your bot PAT (the master token) and the per-job read/write API key that the tool service uses internally. If an agent were somehow compromised, it could not exfiltrate your GitLab PAT or the job’s write credential, because those are not present.

The agent interacts with GitLab through Mate’s permission-gated tool service. On every tool call, the service:

  1. Verifies the job credential is valid and unexpired
  2. Looks up the job’s authority record
  3. Checks that the requested tool is within the job’s effective permissions

The tool surface the agent sees is filtered to match its authorities — tools outside the permitted set are not advertised and cannot be called. This check runs on the server side, not inside the agent process. The agent cannot grant itself additional permissions.

approve_mr is not a grantable authority. No configuration can enable it. The permission model lets you grant commenting today (and, once their tools are enabled, pushing to or merging a merge request) — but approval is always a human action. This is a deliberate separation of duties.

Every job runs in its own container that is created at dispatch time and destroyed when the job ends. Containers are not reused across jobs or tenants. On shared-infrastructure plans (Starter), the container the agent runs in operates without privileged mode and without access to the Docker socket or the host network stack. (Image build steps, when applicable, run separately under the platform’s control.)

If a job fails mid-run (for example, due to a node failure), the container is discarded. There is no resumption in v1 — the job records as errored and you can re-trigger it.

On the hosted service, the following secrets are stored encrypted using AES-256-GCM:

  • Bot PATs (master GitLab tokens)
  • LLM API keys (OpenRouter or Anthropic)
  • Webhook signing secrets
  • Per-job GitLab API keys

Per-job API keys use column-level encryption separate from disk encryption, so database-level access alone is insufficient to read them. The encryption key is held only by Mate’s control-plane services.

Secrets are write-only in the console — once saved, a key is never displayed again. To rotate a key, overwrite it with a new value.

DataWhere it goes
Repository contentsCloned into the ephemeral job container; discarded when the container is destroyed
Issue and MR contentRead by the agent via Mate’s tool service; sent to your chosen LLM provider under your own API key
LLM prompts and responsesSent directly to your provider (Anthropic, OpenRouter, etc.) — Mate does not proxy or store LLM traffic
Job events and logsStored in Mate’s database and displayed in the console; retained for 30 days

Mate does not send your repository code or issue content to any third party beyond the LLM provider you configured. Your LLM provider’s data handling terms govern what happens on their side.

Every GitLab webhook call is verified against the secret token you configured (GitLab’s X-Gitlab-Token mechanism). Mate rejects any request that does not carry the correct token, so unauthorized parties cannot trigger jobs by sending forged webhook payloads.