@infra-tools/agentic-ui-opa-authorizer
v1.2.3
Published
Optional runtime plugin that gates ToolRegistry / ComponentRegistry reads via OPA decisions (Open Policy Agent). Slice OPA-B / ADR-040. Stays outside the core lib per ADR-010 D4.
Readme
@infra-tools/agentic-ui-opa-authorizer
Optional runtime plugin for @infra-tools/agentic-ui that gates ToolRegistry and ComponentRegistry reads through Open Policy Agent (OPA) decisions. Lets you express per-tool / per-widget authorization in Rego instead of TypeScript predicates.
Slice OPA-B / ADR-040. Lives outside the core lib per ADR-010 D4 — adopters who don't want OPA pay nothing.
Need simpler authorization?
provideCatalogCapabilityAuthorizer(ADR-033) in the core lib already handles lifecycle-flag-based deny-lists from the catalog. This package is for richer, policy-expression-based decisions.
Install
npm install @infra-tools/agentic-ui-opa-authorizerPeer: @infra-tools/agentic-ui >=1.2.0 — the plugin composes onto its RegistryBase.setScopePolicy() seam.
Wire it up
import { provideAgenticUi, provideAgenticPlatform } from '@infra-tools/agentic-ui';
import { provideOpaAuthorizer } from '@infra-tools/agentic-ui-opa-authorizer';
export const appConfig: ApplicationConfig = {
providers: [
provideAgenticUi({ tools: [...], widgets: [...] }),
provideAgenticPlatform({
catalogUrl: 'https://catalog.example.com',
tenantId: 'acme',
getToken: () => oidc.getAccessToken(),
capabilityAuthorizer: false, // disable lifecycle-flag deny-list authorizer
}),
provideOpaAuthorizer({
catalogUrl: 'https://catalog.example.com',
tenantId: 'acme',
getToken: () => oidc.getAccessToken(),
subject: () => ({ persona: persona.active(), tenant: tenantId }),
cacheTtlMs: 5_000,
onMiss: 'allow',
}),
],
};How it works
- Composing scope policy. Installs a policy on
ToolRegistry+ComponentRegistrythat consults a per-(kind, name)decision cache. - Cache misses. Default to allow (configurable to deny) and fire a background OPA call. Decisions are cached for
cacheTtlMs. - Decision point. Resolves via the catalog server's
/policy/decideendpoint (ADR-040 / slice OPA-A) — the actual Rego evaluation lives there, not in the browser. - Inspectable.
OpaAuthorizerServiceis a public injectable — callservice.cache()to inspect decisions,service.refresh(kind, name)to force re-evaluation.
Companion server-side piece
This plugin is the runtime client. The catalog server's /policy/decide endpoint (slice OPA-A) is the actual Rego evaluation point. Pair this package with a catalog server build that includes the OPA-A slice.
Full design rationale
- ADR-040 — OPA policy integration
- ADR-010 — Platform principles + Apache 2.0 (why this lives outside core)
Compatibility
| Tool | Version |
|------|---------|
| @infra-tools/agentic-ui | ≥ 1.2.0 (peer) |
| Angular | 21+ |
| Node.js | ≥ 20.19 |
| TypeScript | 5.9+ |
