> For the complete documentation index, see [llms.txt](https://docs.visdom.virtuslab.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.visdom.virtuslab.com/visdom-control-plane/integrating-a-product.md).

# Integrating a product

The contract every Visdom product implements to be managed by the Control Plane.

A product joins the suite by implementing four things against the Control Plane. Context Fabric, AI Tracing and Orchestrator implement all four today; the AI Gateway will follow the same contract.

## 1. Ask for effective permissions

Before an action, the product asks what the caller may do:

```http
GET /api/v1/permissions/effective?subject=<oidc-sub>&project=<slug>
Authorization: Bearer <product service-account token>
```

```json
{ "user_id": "3f0c…", "permissions": ["context-fabric", "context-fabric.operator"] }
```

* Pass exactly one of `user_id` or `subject`, and at most one of `project_id` or `project` (slug).
* `group=projects` returns everything at once, workspace keys separately and project keys by slug – the shape a product caches for a session:

```json
{ "user_id": "3f0c…", "workspace": ["context-fabric"], "projects": { "payments": ["context-fabric.viewer"] } }
```

* The response carries an `ETag` and `Cache-Control: private, max-age=60`. Send `If-None-Match` to get `304` when nothing changed.
* A person may read only their own permissions; admins and machine principals may read anyone's. A disabled user gets an empty set.
* A role key is meaningful only together with the product's sign-in key (`context-fabric` above). Check both.

## 2. Receive project sync

When a project or its repositories change, the Control Plane calls the product:

```http
POST /api/v1/sync/control-plane/projects
Authorization: Bearer <control-plane-m2m token>
traceparent: 00-…
Content-Type: application/json

{ "slugs": ["payments"] }
```

The body names the projects that changed, not what changed. The product re-reads them from the Control Plane. Delivery comes from a transactional outbox: at least once, retried with backoff from 5 seconds up to 5 minutes until the product answers with success. Handlers must be idempotent. Context Fabric listens on `/admin/sync/control-plane/projects`; the others on the path above.

## 3. Read repositories and the repository token

* `GET /api/v1/repositories` – every repository in every project, with branch and GitHub App installation ID. Machine principals and admins only.
* `GET /api/v1/projects/{id}/repository-secret/value` – the project's decrypted repository token. Machine principals and admins only.

## 4. Serve a dashboard summary

The suite dashboard calls `GET /api/v1/dashboard/summary` on the product with the signed-in person's token and merges the answer with the other products'. The product decides what that person may see.

## Identity wiring in Keycloak

| Client                 | Direction                | Purpose                                                                         |
| ---------------------- | ------------------------ | ------------------------------------------------------------------------------- |
| `visdom-control-plane` | UI                       | The Control Plane SPA, authorisation code with PKCE, audience `control-plane`   |
| `control-plane-m2m`    | Control Plane → products | Project sync; audiences of each product                                         |
| `<product>-m2m`        | Product → Control Plane  | Effective permissions, repositories, repository token; audience `control-plane` |

A product's UI can also use the shell endpoints – `/api/v1/me`, `/api/v1/me/theme`, `/api/v1/me/default-project` and `/api/v1/workspace/settings` – so that theme, selected project and timezone stay the same across the suite. CORS allows only the origins configured in `CP_SUITE_*_URL`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.visdom.virtuslab.com/visdom-control-plane/integrating-a-product.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
