Sonar MCP security and profiles
Understand MCP bearer authentication, profile tool limits, and the separate Sonar API and storage permissions.
Sonar MCP separates endpoint access, the tools exposed by a server process, and the permissions of its downstream credentials. A profile limits the MCP tool surface; it does not necessarily limit the backend credential to the same capabilities.
Authorization boundaries
For HTTP, every /mcp request must present the shared BBM_MCP_AUTH_TOKEN. The server refuses
to start without this token. It selects BBM_MCP_PROFILE at startup, not from the caller's token;
all clients of that process receive the same profile. The /health endpoint is unauthenticated.
The client bearer is not forwarded to Sonar. Sonar tools use a separately configured backend
credential, and tool callers cannot override that Authorization header. Sonar authenticates
the credential and checks each endpoint's authorization policy.
Pentest has a narrow tool surface, not a narrow backend key
The pentest process uses SONAR_API_KEY, shared with the fuzzing worker. Sonar recognizes it
as the apikey service identity, which satisfies every service authorization policy, including
Admin. It does not grant the human-only HumanAdmin policy. The MCP allow-list limits calls
through MCP; the backend key does not independently enforce that same pentest tool boundary.
Tiers
Every registered tool declares one tier. Tiers control MCP registration, not Sonar API roles:
| Tier | Capability |
|---|---|
asset-read | Read programs, scopes, and discovered assets. |
read | Read workflow, scan, worker, and resolution state. |
author | Structurally validate a complete workflow document. |
recon-execute | Start a scan through the simple scan-creation boundary. |
write | Read ingest schemas and upsert approved asset records. |
admin | Consequential workflow, scan, worker, and resolution operations. |
storage | List, read, download, and upload objects in allowed buckets. |
Profiles
The process must set BBM_MCP_PROFILE. Missing or unknown values stop startup.
| Profile | Tiers | Effective purpose |
|---|---|---|
asset-read | asset-read | Inventory-only coordinator surface. |
readonly | asset-read, read | Inventory plus the allow-listed workflow and scan reads. |
pentest | asset-read, read, recon-execute, storage | Inventory, workflow/scan reads, simple create_scan, and storage tools. |
astrix-author | asset-read, read, author | Inspect Sonar and structurally validate a workflow; no persistence or execution. |
recon-executor | asset-read, read, author, recon-execute | Inventory reads, simple scan creation, per-scan status, and compatible frozen result reads. |
sync | asset-read, write | Inventory reads plus approved asset synchronization. |
admin | all tiers | All registered tools, including storage tools. |
storage | storage | Direct object access without a Sonar backend token. |
For every non-admin profile, the effective tool set is:
Only enabled tools are registered. The allow-list matters: recon-executor has read and
author tiers but exposes only Inventory reads, create_scan, get_scan, and list_scan_results.
It does not inherit every tool in those tiers. The admin profile enables all tiers without a
separate tool allow-list.
Prompts use a separate per-profile allow-list. Connecting to one profile does not reveal every
skill installed in the server package. The storage profile exposes no skill prompts.
Sonar backend credentials
Profiles that call Sonar require the following environment variable at startup:
| MCP profile | Backend credential variable | Sonar service identity |
|---|---|---|
asset-read | SONAR_SERVICE_TOKEN_ASSET_READ | asset-read |
readonly | SONAR_SERVICE_TOKEN_READONLY | readonly |
pentest | SONAR_API_KEY | apikey (all service policies) |
astrix-author | SONAR_SERVICE_TOKEN_ASTRIX_AUTHOR | astrix-author |
recon-executor | SONAR_SERVICE_TOKEN_RECON_EXECUTOR | recon-executor |
sync | SONAR_SERVICE_TOKEN_SYNC | sync |
admin | SONAR_SERVICE_TOKEN_ADMIN | admin |
storage | None | Does not call Sonar |
These mappings assume each credential matches its corresponding Sonar ServiceTokens
configuration. Sonar derives the identity from the token value, not the MCP profile name.
Profile-scoped service identities must be explicitly allowed by the endpoint policy. The
apikey identity satisfies all service policies; the admin identity is included in all current
service policies. Neither service identity receives the human Admin role required by HumanAdmin.
Storage permissions
The pentest, admin, and storage profiles expose list_objects, read_object,
download_object, and upload_object. These tools bypass the Sonar API and use the process's
MINIO_ENDPOINT, MINIO_ACCESS_KEY_ID, MINIO_SECRET_ACCESS_KEY, and MINIO_USE_SSL configuration.
MCP_STORAGE_BUCKETS is a per-bucket allow-list, for example workers:rw,scan-results:ro:
- A listed bucket permits listing, reading, and downloading objects.
- Only a bucket marked
rwpermits uploads. Uploads can overwrite an existing object key. - An unlisted bucket is denied; an empty allow-list received by the MCP process permits no bucket access.
- The allow-list applies to whole buckets, not per-program or per-object ownership.
Storage credentials must also permit the requested operation in MinIO/S3. The MCP bucket list
does not itself configure storage-side policy or prove those credentials are equally restricted.
The current Sonar Compose configuration uses workers:rw,scan-results:rw when the host-side
MCP_STORAGE_BUCKETS variable is unset or empty. A non-empty value overrides that default.
Setting MCP_STORAGE_BUCKETS= in .env does not disable storage access; denying all buckets
requires an empty allow-list in the container's effective environment, for example through an
explicit Compose override.
The storage-only profile needs no Sonar backend token. Missing MinIO credentials fail when an operation needs the storage client, rather than preventing MCP startup.
Deployment boundaries
- The public
pentestStreamable-HTTP endpoint is bearer-gated and reverse-proxied through Caddy. Its Sonar calls use the shared API key authorized for all service policies, but notHumanAdmin; its storage calls use MinIO credentials. - The
asset-readandastrix-authorHTTP services are private loopback-bound identities with independent bearer gates and backend service tokens. Do not publish them through Caddy. - The backend recon control plane uses its service identity directly; the current Sonar Compose
stack deploys no public
recon-executoror standalonestorageMCP listener. - Local stdio is a process boundary rather than an HTTP bearer boundary. Its profile is mandatory;
profiles that call Sonar also require their configured backend credential. Storage operations
need their own bucket allow-list and MinIO credentials. Use
adminonly when the local client should have explicit administrative authority.
Public pentest policy
The public pentest profile exposes Inventory reads, seven workflow/scan reads, create_scan,
and four storage tools. Its operating instructions require the agent to:
- inspect Inventory first;
- select and confirm a workflow whose category is exactly
AI; - bind one program UUID in
parameters; - call
create_scanexactly once; and - avoid retrying an uncertain launch.
Agent policy is not hard authorization
The category-AI, bounded-program, and launch-once rules are agent instructions, not hard
enforcement by the simple scan endpoint. The tool rejects unknown top-level arguments but does
not enforce these launch rules. The profile hides other Sonar mutations, but storage uploads
remain available for rw buckets. A program UUID supplied to a scan does not scope storage access.