Evidence
Documentation

Version Latest

Vendor AI audit connectors

Bring the audit and usage logs of third-party AI services into Neural Inverse Govern with pull connectors, configured by organisation administrators, with credentials in the organisation's vault.

Your people use AI services Govern does not sit in front of. Vendor AI audit connectors bring those services' own audit and usage logs into Govern, next to Govern's own ledger, so you can search, read and export them in one place. Pull connectors poll a vendor API; push receivers take events a tool sends.

Vendor events show what the vendor reported. They do not give Govern any control over the vendor's service.

How it runs

  • Polling runs in the compliance plane (keystone-comply), which the Kubernetes chart deploys as its own workload. It reads the enabled connectors from the server every 30 seconds (NI_COMPLY_CONFIG_REFRESH_INTERVAL) and runs one polling loop per connector and organisation.
  • Credentials are written to the organisation's Keystone Vault, mount keystone-comply, one secret per connector, and never returned. Responses carry only credential.configured, credential.version and credential.updated_at.
  • Compliance keys are never used for inference: the model gateway reads provider keys from another vault path.
  • Every vendor call goes through the outbound guard: loopback, private, link-local, carrier-grade NAT and metadata addresses are refused unless the operator lists the network in NI_AUTH_OUTBOUND_ALLOW_PRIVATE_CIDRS. No proxy is used, and redirects are followed only within the same scheme, host and port.
  • A failed vendor call is reported by class, never by the vendor's text: unauthorized, forbidden, not_found, rate_limited, vendor_rejected, vendor_unavailable, destination_blocked, destination_not_allowed, redirect_refused, timeout, unreachable, tls_error, invalid_response, credentials_missing, credentials_unavailable, poll_failed.

Set up a connector

The console page is Manage > Integrations > Vendor AI audit connectors. Through the API:

  1. Store the credential (vendoraudit.connectors:manage, Owner and Admin):

    PUT /api/v1/vendor-audit/connectors/anthropic/credentials
    {"credentials": {"api_key": "<Compliance API key>"}}
  2. Test it without storing anything new: POST /api/v1/vendor-audit/connectors/anthropic/test. The answer is {ok, code, http_status, message, tested_at, latency_ms, stored}; a failed vendor call is 200 with ok: false and a class.

  3. Turn it on with a poll interval (60 to 86400 seconds) and settings:

    PATCH /api/v1/vendor-audit/connectors/anthropic
    {"enabled": true, "poll_interval_seconds": 900, "settings": {"ingest_chats": "false"}}

    Enabling without a stored credential is 409 credentials_required.

  4. Poll now if you do not want to wait: POST .../poll answers 202; the compliance plane polls at its next refresh.

Removing the credential (DELETE .../credentials) turns the connector off and deletes every vault version.

Settings are strings. A setting can turn off what the deployment collects; it can never turn on what an operator turned off with a NI_COMPLY_* variable.

Pull connectors

ConnectorVendor APICredential fieldsSettings
anthropicAnthropic Compliance API (Claude Enterprise)api_keyingest_sessions, ingest_chats
openaiOpenAI Compliance API (ChatGPT Enterprise)admin_api_key, workspace_id, organization_idingest_usage
azure-openaiAzure Monitor metrics, activity log, Log Analyticstenant_id, client_id, client_secret, subscription_id, resource_group, account_name, workspace_idingest_metrics, ingest_activity_log
aws-bedrockCloudWatch Logs (Bedrock invocation logs)access_key_id, secret_access_key, session_token, regionlog_group_name
gcpCloud Logging (Vertex AI, Gemini Code Assist)project_id, client_email, private_key
copilotGitHub Copilot seats, usage and metricsapi_key, github_org
tabnineTabnine audit logs and usagetoken, server_urlingest_usage, ingest_agent_usage
gemini-workspaceGoogle Admin SDK Reports, Gemini in Workspace appsclient_email, private_key, admin_email, customer_id
m365-copilotOffice 365 Management Activity API, Audit.Generaltenant_id, client_id, client_secret
aws-q-developerCloudTrail LookupEventsaccess_key_id, secret_access_key, session_token, regionevent_sources (default q.amazonaws.com)
openai-platformOpenAI Admin API: audit logs, hourly usage, daily costsadmin_api_keyingest_usage, ingest_costs
anthropic-consoleAnthropic Admin API: usage, costs, Claude Code usage, compliance activitiesadmin_api_keyingest_usage, ingest_costs, ingest_claude_code, ingest_activities (off by default)
xaixAI Management API audit eventsmanagement_key, team_id
mistralMistral Admin API audit logs (Preview, Enterprise)admin_api_key
openrouterOpenRouter activity, one settled day per request, last 30 daysmanagement_key
cursorCursor Admin API audit logs (Enterprise)api_key
gitlab-duoGitLab group audit events; Duo usage through GraphQLaccess_token, group_path, server_urlai_events_only (on), ingest_duo_usage (off)
atlassianAtlassian organisation events stream (Atlassian Guard; Rovo included)api_key, org_id
slackSlack Audit Logs API (Enterprise Grid)tokenactions
box-aiBox admin event streamclient_id, client_secret, enterprise_idevent_types (default Box AI events)

Vendor notes

  • Gemini for Workspace. Reports can arrive hours late, so each poll reads six-hour windows starting two hours before the last finished window; events are deduplicated by id. The service account needs domain-wide delegation of admin.reports.audit.readonly, acting as an administrator.
  • Microsoft 365 Copilot. The connector starts the tenant's Audit.General subscription when none exists, keeps CopilotInteraction, ConnectedAIAppInteraction and AIAppInteraction records, and reads at most seven days back. The application needs ActivityFeed.Read.
  • Amazon Q Developer. Event sources are a setting (up to five *.amazonaws.com hosts), because some accounts show amazonq.amazonaws.com or codewhisperer.amazonaws.com. CloudTrail holds 90 days of one account and region, and prompt text is not part of it.
  • Usage and cost reports are read once they settle: an hourly bucket an hour after it ends, a daily bucket a day after.
  • Records without an identity or a time fail the poll as invalid_response instead of being dropped, so a vendor format change shows as a failing connector, not lost events.
  • Self-hosted Tabnine and GitLab. server_url must be https, without credentials, and on NI_COMPLY_TABNINE_SERVER_HOSTS or NI_COMPLY_GITLAB_SERVER_HOSTS when the operator sets them. A server on a private network also needs its network in NI_AUTH_OUTBOUND_ALLOW_PRIVATE_CIDRS.
  • Not covered: Cohere, Groq, Together AI, Fireworks, DeepSeek and the Perplexity API publish no audit or usage feed readable with a key. Windsurf, Devin, JetBrains AI, Sourcegraph Cody and Zoom AI Companion have no audit API whose format could be confirmed. Any service that can forward JSON can use the audit webhook.

Known defect: duplicate suppression across organisations

The ten connectors anthropic, openai, azure-openai, aws-bedrock, gcp, copilot, tabnine, gemini-workspace, m365-copilot and aws-q-developer use event ids that are not scoped to the organisation, and events are deduplicated on that id. When two organisations on one installation connect the same vendor tenant, or produce the same synthetic id (for example Tabnine's per-day usage), one organisation's event can silently suppress the other's. On a single-organisation installation this does not arise. The feed connectors (openai-platform to box-ai) and the push receivers derive ids from the organisation and are not affected.

Health

Each connector reports a state and a summary:

StateMeaning
not_set_upOff, no credential
offCredential stored, turned off
pendingEnabled, never polled
healthyThe last poll succeeded
failingThe last poll failed (for example "Failing (3 polls)"), with last_error_code, last_error_http_status and last_error_message
staleNo success for three intervals and ten minutes

The compliance plane's own health is watched by selfguard (GET /metrics/selfguard with NI_COMPLY_SERVICE_TOKEN).

Read the events

The console page is Audit > Vendor AI activity.

RoutePermissionWhat
GET /api/v1/vendor-audit/eventsaudit:readEvents, newest first, without payloads. Filters vendor, user (email or vendor user id), action, source_type, from, to; paging limit (1 to 200) and page_token
GET /api/v1/vendor-audit/events/{eventID}audit.vendor_content:viewOne event with the vendor's raw_payload and its SHA-256 content_hash
POST /api/v1/vendor-audit/events/exportaudit:create and audit.vendor_content:viewA signed export; see Exports

Payloads can hold chat content and Claude Code transcripts, so reading them needs audit.vendor_content:view, which the read-only roles do not hold (Auditor, Owner and Admin do).

Permissions

PermissionHeld byRoutes
vendoraudit.connectors:readRead-only roles, Owner, AdminConnector list and detail, token list
vendoraudit.connectors:manageOwner and AdminConfigure, credentials, test, poll, tokens
audit:readRead-only roles, Auditor, Owner, AdminEvent list, export list
audit.vendor_content:viewAuditor, Owner, AdminEvent detail with payload, export request and download

Every change is recorded in the audit log (vendor_audit.*) in the transaction that makes it; credential changes name the fields, never the values. A connector, event or export of another organisation answers 404.

Last reviewed 17 October 2026View as Markdown

Vendor AI audit connectors · Docs · Neural Inverse