# Connectors

Source: https://www.testifysec.com/docs/badger/concepts/connectors/

How Badger connectors give the agent read and write access to an enclave's Jira, Confluence and GitLab, and what each one is locked to.

An enclave already runs its own source host, issue tracker and wiki. A connector lets the agent read those services, and write to them where the administrator allows, as the signed-in developer.

 

| Piece | Status |
| --- | --- |
| Shared connector library and reference connector | Available on `main` |
| One administrator-set marking on every result | Available on `main` |
| Jira Data Center connector | Available on `main` |
| Confluence Data Center connector | Available on `main` |
| GitLab self-managed connector, read tools | Available on `main` |
| GitLab write tools | Available on `main` |
| Turning a connector on through the signed profile | Designed, not built |

 

A managed Badger build cannot load a connector yet. The connectors run and are tested as standalone MCP servers; the profile entry that admits them to a session is a later change.

 

## How a connector runs

 

Each connector is one static Go binary with no third-party dependencies, built with `CGO_ENABLED=0`. It speaks MCP over standard input and output. The agent's worker starts it as a local MCP server inside the worker boundary, so a connector never opens a listening socket. The MCP implementation is about a hundred lines in `testifysec/connectors/internal/connector/stdio.go` instead of the official SDK, which would have added nine third-party modules to a process that holds a user's credential.

 

## What a connector is locked to

 

These limits are in the shared library on `main` (`testifysec/connectors/internal/`) and apply to every connector:

 

- **One service.** The HTTP client is bound to one base URL. It refuses any other host, any path outside the base, any redirect that leaves the base, and plain HTTP (except to loopback in tests). It ignores proxy environment variables. Responses are capped at 8 MiB.
 - **The developer's own credential.** The connector reads a short-lived token from a file on every request and sends it as the developer. There is no shared service account. In the design the session broker provisions that file per user.
 - **Configuration from the administrator only.** A connector takes its settings from flags or `BADGER_CONNECTOR_*` environment variables. In a managed session the model, user settings and repository files have no way to set them, and `mcp add`, plugin install and the connect routes stay refused.
 - **Untrusted output.** Every result is wrapped in an `untrusted-external-content` block naming the source and tool and capped at 48 KiB. Any credential the connector itself sent is replaced with `[redacted]` before the result leaves it.
 - **Fixed error text.** Authentication, permission, not-found, rate-limit and server errors become short fixed messages. Validation errors keep at most 300 bytes of the service's message, with credentials removed.

 

## Read and write tools

 

Every tool is registered as read or write. Without `--enable-writes`, write tools are not registered at all: they are absent from `tools/list`, and calling one by name returns "unknown tool". Read tools carry the MCP annotation `readOnlyHint: true`, write tools `false`.

 

The connectors provide:

 

| Connector | Read | Write (with `--enable-writes`) |
| --- | --- | --- |
| Jira | search with JQL, get an issue, list comments | add a comment, create an issue, transition an issue |
| Confluence | search with CQL, get a page as Markdown, list child pages, list spaces | create a page, update a page at its current version |
| GitLab | get a project, search issues, get an issue, list and get merge requests, get a merge request diff, get a file, list pipelines, get a job log | create an issue, add a note to an issue or merge request |

 

GitLab write tools refuse any line starting with `/`, because GitLab runs it as a quick action, and refuse labels that carry the marking prefix. Push, merge, approve, branch and tag creation, pipeline retry and settings changes are deliberately absent: code reaches a repository through Pushgate, not through a connector.

 

## Classification

 

Each connector has one classification, the marking the administrator sets for the service it reads, and every result it returns carries that marking. The marking belongs to the connector, not to individual items. See [classification markings](https://www.testifysec.com/docs/badger/concepts/classification) for the rule and its status.

 

## Admission (designed)

 

The planned profile entry for a connector names the binary's SHA-256, the base URL, the token and CA file paths, whether writes are on, the service's marking, and per-tool permissions such as `"jira_add_comment": "ask"`. Only the administrator's signed profile will set it. Until it is built, there is no supported way to attach a connector to a managed session.

Reference generated from the product documentation. Match commands and support details to your installed release.
