---
name: vinkius-department-copilots
description: 'Teaches the department-copilots pattern on @vinkius/connect: each organizational unit (Finance, Dispatch, Warehouse, Fleet Ops) becomes a first-class user whose external_id is a stable department key, owning shared durable connectors, credentials, spend and revocation, while humans merely operate the copilot. Explains naming, per-team connector configuration, headless onboarding, audit trail ownership and graceful deprovisioning. Use when building internal AI assistants scoped to teams or roles rather than individuals. Prerequisite: vinkius-connect-core.'
license: Apache-2.0
metadata:
  author: Vinkius
  package: "@vinkius/connect"
  pattern: "user = department / team"
  docs: "https://vinkius.com/learn/connect-sdk/build-department-copilots"
---

# Department copilots

Applies the machinery from vinkius-connect-core. The only choice this pattern makes is what a "user" is: here, a department.

## Why the team is the right actor

Credentials that belong to a *team* cannot live in a person's account: staff turn over, permissions drift, and "whose token was used?" becomes an audit nightmare after the first departure. Model the team as the user and the problem disappears: `dept-warehouse` owns the WMS connection forever; the copilot sees Warehouse's tools and never Finance's, because capability queries resolve inside one `external_id` and there is no path across it.

## Naming and configuration rules

- Prefix every department id (`dept-`, or your org's own) so a team key can never collide with a human id from another part of the system. Treat the id as a durable identifier, like a database primary key: derived from stable org data, never from a mutable display name.
- Declare which connectors each department may use as *configuration*, not code branches: one map from department to connector list, consumed by both the capability query (`include`) and the admin UI. Adding a team becomes one new entry, not a new feature.
- Attach `kind: 'department'` (plus the team code) through `user.ensure()` so dashboards and support tooling can filter by actor type. Metadata is non-secret by contract.

## Provisioning and operation

- Onboarding a department is an admin action, run once, headless: for each connector, `connect()`, then for static-token connectors `credentials.set()` with the team's secret from your secret manager; for OAuth connectors, an authorized admin completes the provider consent inside `connect()`. Afterwards, read `user.connectors()` and surface each status so gaps (`needs_credentials`, `disabled`) are visible to the admin console rather than discovered at 2 AM.
- At ask time: resolve the requesting human's department from your directory (never from a request body), then load that department's capabilities. The copilot answers as the team: the tools it can see, the spend it can burn, and the revocation it can trigger all belong to the team.
- The audit trail is split on purpose: Vinkius permanently knows only `dept-finance`, which is what guarantees team-level isolation; the who-asked record is yours to keep in your own logs. Do not attempt to send user identities to the platform, they are not part of the contract.
- Granting or removing a team is a single operation: create the id and connect its list; retire it with `user.delete()` / per-connection `disconnect()`. Blast-radius isolation means one department's token dying changes nothing for the others.

## Verify it works before shipping

Provision two departments with overlapping humans and disjoint connector sets; assert each copilot's tool list matches its configuration exactly, assert one department cannot findCapability another's tool, and assert an idempotencyKey on the mutating action stops a double-submit from double-executing.

Docs with the full walkthrough: https://vinkius.com/learn/connect-sdk/build-department-copilots
