Agent directories Module

Vaks PM · Integration guide · Agent directories · July 2026

What you will end up with. The AI agent identities that already exist in your Microsoft Entra tenant, mirrored into Vaks PM as agent accounts — each owned by a named human, read-only, and unable to authenticate until you deliberately give it a token. This guide assumes no prior knowledge of the product and takes about 15 minutes end to end.

What this does — and what it does not

Vaks PM treats AI agents as first-class actors: an agent is a user account with kind = AGENT, a mandatory human owner, a trust level, and an explicit list of capabilities. A directory connector saves you from creating those accounts by hand when your organization already declares its agents somewhere else. It reads the agent list from that platform on demand and mirrors it.

Being precise about the boundaries matters here, because this integration is deliberately narrow:

On re-sync, only the agent's name, status and model fields are refreshed. Trust level, capabilities and owner — everything a human decided — are never overwritten.

Which directories can I connect? The connector is a provider-agnostic mechanism — the setup flow (pick the platform, enter its credentials, set a default owner, sync) is the same whatever the source. Today one provider ships: Microsoft Entra Agent ID, and this guide walks through it. Others (AWS Bedrock AgentCore, Google Vertex AI) are planned and will slot into the same flow. For any platform without a native connector, the inbound registration path already works now — the platform pushes its agents to an API, with no app registration to create on your side.
Is a connector the right choice? Use one when a directory already holds your agent list and you want it mirrored. If instead your agent platform can call an API when it provisions an agent, the push model in inbound registration is simpler. The two can coexist — they use separate identity namespaces, so the same agent imported both ways would appear twice.

Prerequisites

You need rights on both sides, and they are usually held by two different people. Confirm both before starting. The far side depends on the platform you are connecting; the row below is for Microsoft Entra, the provider available today — another provider would ask for its own service credentials in place of an app registration.

SideWhat you needWhy
The source directory
(Microsoft Entra today)
For Entra: permission to create an app registration, plus a Privileged Role Administrator or Global Administrator to grant admin consent The connector reads the platform's agent identities with its own service credentials. For Entra this is an application permission, which only takes effect once an administrator consents on behalf of the whole tenant.
Vaks PM The agent:manage permission — held by any organization administrator, or by a user granted the orthogonal AI administrator role All agent and connector screens sit behind this single permission. It can never be held by an agent itself.
Vaks PM At least one active human user to designate as default owner Every agent must be owned by an active human. Entra does not expose an owner for agent identities, so without a default owner every agent is skipped.
If you are an AI administrator rather than a full administrator, open the default-owner dropdown before you start. Populating it requires the ability to list users; if your grant does not include it, the dropdown comes up empty and silently stays that way. You will be able to save the connector and it will then import nothing. Have a full administrator create the connector, or set the default owner for you.

Step 1 — In Microsoft Entra

You are creating a dedicated app registration whose only job is to read the agent list. It authenticates as itself — no user is involved, no one signs in — using the OAuth 2.0 client-credentials flow.

1.1 Create the app registration

Navigate to Microsoft Entra admin center → Identity → Applications → App registrations → New registration.

After registration, copy two values from the Overview page — you will paste both into Vaks PM:

1.2 Grant the Graph permission

Go to API permissions → Add a permission → Microsoft Graph → Application permissions, and add exactly one:

AgentIdentity.Read.All

Then press Grant admin consent for <tenant> and confirm that the permission's status column reads Granted. This is the step most often missed: without consent the permission is listed but inert, and the connector's Test button will fail with an explicit 403.

Why an application permission. The connector runs without a signed-in user, so delegated permissions do not apply. AgentIdentity.Read.All is read-only and scoped to agent identities — it grants no access to users, groups, mail or files. This is the entire Graph surface the integration touches.

1.3 Create a client secret

Go to Certificates & secrets → Client secrets → New client secret, choose an expiry that fits your rotation policy, and copy the secret Value immediately — Entra shows it once and never again.

Set the optional expiry date so you get a warning. Vaks PM cannot know when the Entra secret expires on its own — so the connector form has an optional Secret expiry date field. Fill in the date Entra shows when you create the secret, and Vaks PM emails your admins 14 days before it lapses. Leave it blank and there is no warning: the secret lapses silently, Sync now starts failing with an authentication error, and the mirror stops advancing. Rotating it is a two-minute job: create a new secret in Entra, paste it into the connector, update the expiry date, save.

1.4 Alternative — certificate authentication (no secret, nothing to watch for expiry)

Instead of the client secret from step 1.3, this app registration can authenticate with a certificate (private_key_jwt) — see the detailed procedure in the SSO OIDC guide (generating the key/certificate pair, uploading the .cer, the thumbprint). It is the same Entra app as in step 1.1: one certificate is enough if you reuse this app for other Vaks PM Entra integrations.

Unlike a client secret, a certificate has no expiry date to track in Vaks PM — the Secret expiry date field only applies to secret mode. Choose the certificate's validity period at creation time instead.

Step 2 — In Vaks PM

Open Admin → Integrations → Agent directories and press Add directory. Choose Microsoft Entra Agent ID as the platform, then fill in the form:

FieldValue
LabelFree text, shown in the connector list. Useful when you run more than one.
Tenant ID (Entra)The Directory (tenant) ID GUID from step 1.1.
Client ID (app registration)The Application (client) ID GUID from step 1.1.
Client secret or certificateThe secret Value from step 1.3, or the thumbprint + private key if using certificate authentication (step 1.4). Encrypted at rest (AES-256-GCM) and never displayed again. Leave blank when editing to keep what is stored; a private key on file takes precedence over the secret.
Default owner for imported agentsAn active human who becomes the owner of every imported agent. Required in practice for Entra — see the warning below.
Enable this connectorTick it. Sync now stays greyed out until the connector is enabled and saved.
Set a default owner, or you will import nothing. Every agent in Vaks PM must have an active human owner. Entra's agent identities do not carry one, so the default owner is the only source. Agents with no resolvable owner are skipped, and the sync says so: it reports Nothing imported: N agent(s) skipped because no owner could be resolved instead of a success. Set the default owner and re-sync.
The required-field asterisks are not enforced on save. A connector with an empty tenant ID or client ID saves without complaint; the problem only surfaces when you press Test. Always run the test in step 3 rather than trusting a successful save.

Two constraints worth knowing before you commit: the platform choice is immutable after creation — switching means deleting and recreating — and nothing stops you creating several connectors for the same platform, so check the list before adding a duplicate.

Step 3 — Test, then sync

Press Test on the connector card. This acquires a token and makes a single, minimal Graph call. It changes nothing and persists nothing — run it as often as you like.

Once the test passes, press Sync now. The connector enumerates the tenant's agent identities and mirrors them.

Then confirm the result where it counts: Admin → Users & Identity → Agents should now list the imported agents, each showing its owner and the Draft only trust level.

Two limits worth knowing. A sync enumerates at most 500 agents and each Graph call times out after 10 seconds. Beyond 500, the excess is truncated silently. And because there is no scheduler, an agent added in Entra today will not appear in Vaks PM until someone syncs — so a periodic sync belongs in whatever runbook covers your agent onboarding.

Step 4 — Activate an agent

An imported agent exists but is inert. It has no token, cannot sign in, cannot be granted a local password, holds no licence seat, and carries a single capability: read:project. This is deliberate — the import is a governance step, not an authorization step, and nothing in Entra can shortcut it.

To put an agent to work, open Admin → Users & Identity → Agents, select it, and:

  1. Confirm the owner. The default owner from the connector applies to every agent it imported; reassign per agent so accountability lands on the person who actually operates it.
  2. Set the trust level and capabilities to the minimum the agent needs. Capabilities are a hard ceiling: an agent's effective rights are its role's permissions intersected with its token's scopes intersected with its capabilities. Finance, client data, administration and time logging can never be granted to an agent, whatever you tick.
  3. Issue an API token. The secret is displayed exactly once — capture it at that moment. Expiry is mandatory, defaulting to 90 days.

From that point the agent's actions are attributed to it in the audit log as AGENT, alongside its owner's identity, so every action remains traceable to a responsible human.

Handing out a token by hand does not scale. Issuing a token manually is fine for a few agents. Beyond that — or whenever the agent runs on a platform that can prove its own identity (Kubernetes, Entra / Copilot Studio / Foundry, GitHub Actions) — let the agent authenticate without a distributed secret. See Agent authentication for federation and self-rotating machine credentials.

Alternative — inbound registration

If your agent platform is not Entra, or you would rather have the platform announce its agents as it provisions them, use the push model instead. It needs no app registration.

In Admin → Integrations → Agent directories, under Inbound — a platform declares its agents, use the Agent registration API card to mint an organization API key. The key is automatically scoped to agent:manage and nothing else; an expiry is mandatory (default one year, maximum two).

Your platform then calls:

POST /api/v1/agents
Authorization: Bearer vaks_org_<your-key>
Content-Type: application/json

{
  "name": "Docs drafting agent",
  "externalId": "agent-8842",
  "ownerEmail": "owner@example.com",
  "modelProvider": "anthropic",
  "model": "claude-opus-4-8",
  "hostingRegion": "eu-west"
}

name, externalId and ownerEmail are required; the last three fields are optional descriptive metadata. The call is idempotent on externalId, so re-registering the same agent updates it rather than creating a duplicate — the response returns created: true or false so the caller can tell which happened.

ownerEmail must match an active human in the organization, or the call is rejected with 400. As with the connector, the agent arrives at Draft only with read:project and no token: a human still has to activate it.

Registration creates the identity, not the cost profile. The model and modelProvider fields are descriptive metadata only — they carry no pricing. What an agent costs is set separately, either in Admin → Agents or by API (below), and what it consumes is declared per run. The full lifecycle is: register (identity) → set the costactivate (a human issues the token) → run and report cost.

Setting an agent's internal cost by API

You can keep an agent's internal token cost in step with your provider's pricing from the same integration, without opening the admin panel. Using an organization key scoped agent:manage — the same kind of key as the registration above:

PATCH /api/v1/agents/cost-profile
Authorization: Bearer vaks_org_<your-key>
Content-Type: application/json

{
  "externalId": "agent-8842",
  "costRateInPerKTokens": 0.006,
  "costRateOutPerKTokens": 0.03
}

The agent is found by externalId, the same key as registration. Both rates are in currency per 1000 tokens; at least one is required, and null clears a rate. The response is the updated agent, and the change is written to the audit log with the old and new values.

This sets the internal cost only — never the client billing rate. The two internal rates are what the model costs you (input and output). The rate you charge a client (defaultBillRatePerKTokens) is deliberately not accepted here: an organization key cannot set your selling price. That stays in Admin → Agents, under finance control. If the same externalId exists on more than one source, the call returns 409 — add idpSource to disambiguate.

Troubleshooting

Messages are shown in your interface language. They are reproduced below in English so you can match them exactly.

MessageCause & fix
Access denied (403) — the AgentIdentity.Read.All application permission is missing (admin consent required). The permission was added but never consented, or was consented as a delegated rather than application permission. Return to step 1.2 and confirm the status column reads Granted.
Entra authentication refused: … Tenant ID, client ID or client secret is wrong, or the secret has expired. The trailing text is Microsoft's own explanation and usually names which. Expired secrets are the most common cause on a connector that used to work.
Incomplete configuration (tenantId / clientId / clientSecret). A field was left empty on save. It can also mean the stored secret has become unreadable after an encryption-key rotation — in that case simply re-enter the secret and save.
Connector disabled — enable it before syncing. Tick Enable this connector and save. Test works on a disabled connector; Sync now does not.
Timed out reaching Microsoft. Graph did not answer within 10 seconds. Usually transient — retry. If it persists, check outbound network access and any egress proxy between the instance and graph.microsoft.com.
Unexpected Graph response (HTTP n). / Graph enumeration failed (HTTP n). Graph answered with an unexpected status. A 429 means throttling — wait and retry. Anything else is worth raising with support along with the connector's Last sync line.
Sync reports Nothing imported: N agent(s) skipped because no owner could be resolved The default owner is missing: every agent was skipped for lack of one. Set it and re-sync.
Sync reports 0 created, 0 updated, 0 suspended with nothing skipped The tenant genuinely holds no agent identities — confirm with Test, which succeeds either way.
defaultOwnerId invalide : humain ACTIF requis. The chosen owner is suspended, deleted, or is itself an agent. Pick an active human.

What is logged

Every step here leaves an audit trail, readable under Admin → Security & Compliance → Audit log and exportable to your SIEM:

ActionRecorded
Connector created, updated, deletedActor and target connector. Secrets are redacted — the client secret never reaches the audit log.
SyncPlatform, plus counts of agents created, updated, suspended and skipped. The on-screen message reports the skipped count too; the audit log keeps it after the toast is gone.
Agent lifecycleCreation, suspension, capability and trust-level changes, token minting and revocation — all at critical severity.
Agent activityEvery action an agent takes is attributed to actor type AGENT with its owner's identity attached, and can be filtered on that basis.

Related: all integrations · product & features for the agent governance model · encryption & keys for how connector secrets are protected at rest.