Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
9f1791a
add new lluna client
namrataghadi-galileo May 6, 2026
8d2227d
fix the url
namrataghadi-galileo May 7, 2026
8a31d15
feat(server): migrate /controls + /control-templates onto auth framework
abhinav-galileo May 6, 2026
3a5b7e4
fix(server): keep public docstrings API-level on migrated controls ro…
abhinav-galileo May 6, 2026
8312b99
docs(server): keep binding auth comments generic
abhinav-galileo May 8, 2026
ab9a3f6
feat(server): add runtime auth namespace cutover
abhinav-galileo May 7, 2026
6bc9b46
chore(sdk-ts): regenerate client docs
abhinav-galileo May 7, 2026
717c0b9
fix(server): address runtime auth review feedback
abhinav-galileo May 7, 2026
45ceb25
feat(server): operator-configurable extra forwarded headers on HttpUp…
abhinav-galileo May 8, 2026
479ca86
fix(server): preserve default runtime auth fallback
abhinav-galileo May 8, 2026
5e6811b
feat(server): migrate /controls + /control-templates onto auth framework
abhinav-galileo May 6, 2026
0a2092d
fix(server): keep public docstrings API-level on migrated controls ro…
abhinav-galileo May 6, 2026
e75cbb7
docs(server): keep binding auth comments generic
abhinav-galileo May 8, 2026
90d72af
feat(server): add runtime auth namespace cutover
abhinav-galileo May 7, 2026
33acd7e
chore(sdk-ts): regenerate client docs
abhinav-galileo May 7, 2026
5fe5c6e
fix(server): address runtime auth review feedback
abhinav-galileo May 7, 2026
9a8c8e9
feat(server): operator-configurable extra forwarded headers on HttpUp…
abhinav-galileo May 8, 2026
ecf2b1a
fix(server): preserve default runtime auth fallback
abhinav-galileo May 8, 2026
03047b2
fix(server): harden auth scoping
abhinav-galileo May 11, 2026
3e71661
docs(server): clarify upstream auth failure mapping
abhinav-galileo May 11, 2026
7f696ef
docs(server): explain target principal authorization
abhinav-galileo May 11, 2026
69aaa49
chore(sdk-ts): refresh generated client docs
abhinav-galileo May 11, 2026
7fe90bf
feat(sdk-python): add runtime token auth
abhinav-galileo May 7, 2026
b786759
feat(sdk): make API key header name configurable
abhinav-galileo May 8, 2026
047ba35
fix(sdk): honor API key header for observability
abhinav-galileo May 8, 2026
16b7357
fix(sdk): keep JWT runtime evaluation target-bound
abhinav-galileo May 8, 2026
36ca9f8
fix(sdk): propagate custom API key header
abhinav-galileo May 11, 2026
527a0a9
docs(sdk): note strict JWT runtime target requirement
abhinav-galileo May 11, 2026
db02db8
Merge branch 'main' into feature/64546-add-new-luna-client
namrataghadi-galileo May 11, 2026
84a0b52
Merge branch 'abhi/runtime-auth-namespace-cutover' into test-end-to-end
namrataghadi-galileo May 11, 2026
977571a
merge resolutions
namrataghadi-galileo May 11, 2026
baa8d9c
Merge branch 'main' into test-end-to-end
namrataghadi-galileo May 11, 2026
2894484
create new test branch with all changes
namrataghadi-galileo May 12, 2026
54a789f
fix CI
namrataghadi-galileo May 12, 2026
aa87589
feat(galileo): support internal scorer auth
namrataghadi-galileo May 12, 2026
0cce0bf
feat(galileo): support internal scorer auth
namrataghadi-galileo May 12, 2026
dd252be
add auth and update schema
namrataghadi-galileo May 12, 2026
37efd66
add auth and update schema
namrataghadi-galileo May 12, 2026
74fcbeb
fix(galileo): align luna scorer response schema
namrataghadi-galileo May 12, 2026
5591321
fix(galileo): align luna scorer response schema
namrataghadi-galileo May 12, 2026
7b0a15d
update the schemas and corresponding tests
namrataghadi-galileo May 13, 2026
523524d
update the schemas for scorer
namrataghadi-galileo May 14, 2026
34f430d
update luna client schemas
namrataghadi-galileo May 14, 2026
ad0b2dc
fix tests
namrataghadi-galileo May 14, 2026
e9dea41
update the contract
namrataghadi-galileo May 14, 2026
d428842
fix broken test
namrataghadi-galileo May 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

<!-- version list -->

## Unreleased

### Changed

- **sdk**: Strict `runtime_auth_mode="jwt"` evaluation requests now require both
`target_type` and `target_id`; missing target context raises an error instead
of falling back to API-key auth.

## v7.7.0 (2026-05-07)

### Bug Fixes
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This repository keeps documentation concise. The full documentation lives on the
- [Controls](https://docs.agentcontrol.dev/concepts/controls) — Define and configure control rules
- [Reference](https://docs.agentcontrol.dev/core/reference) — SDK and server API reference
- [Configuration](https://docs.agentcontrol.dev/core/configuration) — Environment variables, auth, and database settings
- [Server auth contract](auth.md) - Pluggable auth modes, HTTP upstream contract, and runtime JWT claims
- [UI Quickstart](https://docs.agentcontrol.dev/core/ui-quickstart) — Run the dashboard and manage controls visually

## Examples
Expand Down
149 changes: 149 additions & 0 deletions docs/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Server Auth Contract

Agent Control keeps authentication and authorization provider-neutral. The server asks a configured provider whether a request may perform an operation, then scopes all data access with the returned `Principal`.

## Operations

Operations are stable strings. Deployers map them to their own permission model.

```text
controls.read
controls.create
controls.update
controls.delete
policies.read
policies.create
policies.update
agents.read
agents.create
agents.update
control_bindings.read
control_bindings.write
runtime.token_exchange
runtime.use
```

## Principal

Providers return a generic principal. Agent Control treats `namespace_key`, `caller_id`, `target_type`, and `target_id` as opaque strings.

```json
{
"namespace_key": "tenant-a",
"is_admin": false,
"caller_id": "user-or-key-id",
"target_type": "session",
"target_id": "target-123",
"scopes": ["runtime.use"],
"expires_at": "2026-05-11T15:00:00Z"
}
```

`namespace_key` is the tenancy boundary. Server queries filter by it, and namespace-aware foreign keys prevent cross-namespace references.

## Auth Modes

Management auth is selected by `AGENT_CONTROL_AUTH_MODE`.

| Mode | Meaning |
| --- | --- |
| `none` | No credentials required. Intended for local development only. |
| `api_key` | Validate caller credentials locally with `AGENT_CONTROL_API_KEYS`. This is the default. `header` is accepted as a backwards-compatible alias. |
| `http_upstream` | POST each management authorization decision to `AGENT_CONTROL_AUTH_UPSTREAM_URL`. |

Runtime auth is selected by `AGENT_CONTROL_RUNTIME_AUTH_MODE`.

| Mode | Meaning |
| --- | --- |
| unset | Use `jwt` when `AGENT_CONTROL_RUNTIME_TOKEN_SECRET` is set. Otherwise runtime requests fall through to management auth. |
| `none` | No runtime credentials required. Intended for local development only. |
| `api_key` | Validate runtime requests with the same local API-key mechanism. |
| `jwt` | Require target-bound runtime tokens minted by `/api/v1/auth/runtime-token-exchange`. |

Common combinations:

| Management | Runtime | Use case |
| --- | --- | --- |
| `api_key` | unset | Existing standalone deployments. |
| `api_key` | `jwt` | Local management keys with short-lived target-bound runtime tokens. |
| `http_upstream` | `jwt` | External identity or authorization service for management, local token verify for high-volume runtime calls. |
| `none` | `none` | Single-process local development. Do not use in production. |

## HTTP Upstream Contract

When `AGENT_CONTROL_AUTH_MODE=http_upstream`, the server sends:

```http
POST {AGENT_CONTROL_AUTH_UPSTREAM_URL}
```

```json
{
"operation": "control_bindings.write",
"context": {
"target_type": "session",
"target_id": "target-123"
}
}
```

The provider forwards inbound `X-API-Key`, `Authorization`, and `Cookie` headers. Add deployer-specific header names with `AGENT_CONTROL_AUTH_UPSTREAM_EXTRA_FORWARD_HEADERS`, for example:

```text
AGENT_CONTROL_AUTH_UPSTREAM_EXTRA_FORWARD_HEADERS=Vendor-API-Key,X-Workspace-Id
```

If `AGENT_CONTROL_AUTH_UPSTREAM_SERVICE_TOKEN` is set, it is forwarded on `AGENT_CONTROL_AUTH_UPSTREAM_SERVICE_TOKEN_HEADER` or `X-Agent-Control-Service-Token` by default.

A successful upstream response is:

```json
{
"namespace_key": "tenant-a",
"is_admin": false,
"caller_id": "user-or-key-id",
"target_type": "session",
"target_id": "target-123",
"scopes": ["runtime.use"],
"expires_at": "2026-05-11T15:00:00Z"
}
```

Only `namespace_key` is always required. `target_type` and `target_id` must be returned together when present. `expires_at` must include timezone information.

Status handling:

| Upstream status | Agent Control result |
| --- | --- |
| `200` | Parse the principal grant. |
| `401` | Authentication error. |
| `403` | Forbidden error. |
| `404` | Not found error. |
| `429` | `503` with a rate-limit detail and `Retry-After` hint when present. |
| Other statuses or upstream network errors | Fail closed with `503`. |
| Malformed `200` principal response | Fail closed with `502`. |

## Runtime JWT Claims

`/api/v1/auth/runtime-token-exchange` is a management-style request. The configured management provider authorizes `runtime.token_exchange` for the requested target. Agent Control then mints its own HS256 JWT with `AGENT_CONTROL_RUNTIME_TOKEN_SECRET`.

The token payload contains:

```json
{
"iss": "agent-control/server",
"domain": "runtime",
"namespace_key": "tenant-a",
"actor_id": "user-or-key-id",
"target_type": "session",
"target_id": "target-123",
"scopes": ["runtime.use"],
"iat": 1778509800,
"exp": 1778510100,
"jti": "opaque-token-id"
}
```

Verification requires the expected issuer, `domain="runtime"`, a valid signature, an unexpired `exp`, and `runtime.use` in `scopes`. The token is accepted only for requests whose `target_type` and `target_id` match the bound target.

The expiry is the earlier of `AGENT_CONTROL_RUNTIME_TOKEN_TTL_SECONDS` and the upstream grant's `expires_at` when supplied. Runtime token TTLs are capped at 86400 seconds.
1 change: 1 addition & 0 deletions evaluators/contrib/galileo/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dev = [
]

[project.entry-points."agent_control.evaluators"]
"galileo.luna" = "agent_control_evaluator_galileo.luna:LunaEvaluator"
"galileo.luna2" = "agent_control_evaluator_galileo.luna2:Luna2Evaluator"

[build-system]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
This package provides Galileo evaluators for agent-control.

Available evaluators:
- galileo.luna: Galileo Luna direct scorer evaluation
- galileo.luna2: Galileo Luna-2 runtime protection

Installation:
Expand All @@ -19,6 +20,15 @@
except PackageNotFoundError:
__version__ = "0.0.0.dev"

from agent_control_evaluator_galileo.luna import (
LUNA_AVAILABLE,
GalileoLunaClient,
LunaEvaluator,
LunaEvaluatorConfig,
LunaOperator,
ScorerInvokeRequest,
ScorerInvokeResponse,
)
from agent_control_evaluator_galileo.luna2 import (
LUNA2_AVAILABLE,
Luna2Evaluator,
Expand All @@ -28,6 +38,13 @@
)

__all__ = [
"GalileoLunaClient",
"ScorerInvokeRequest",
"ScorerInvokeResponse",
"LunaEvaluator",
"LunaEvaluatorConfig",
"LunaOperator",
"LUNA_AVAILABLE",
"Luna2Evaluator",
"Luna2EvaluatorConfig",
"Luna2Metric",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Galileo Luna direct scorer evaluator."""

from agent_control_evaluator_galileo.luna.client import (
GalileoLunaClient,
ScorerInvokeInputs,
ScorerInvokeRequest,
ScorerInvokeResponse,
)
from agent_control_evaluator_galileo.luna.config import LunaEvaluatorConfig, LunaOperator
from agent_control_evaluator_galileo.luna.evaluator import LUNA_AVAILABLE, LunaEvaluator

__all__ = [
"GalileoLunaClient",
"ScorerInvokeInputs",
"ScorerInvokeRequest",
"ScorerInvokeResponse",
"LunaEvaluatorConfig",
"LunaOperator",
"LunaEvaluator",
"LUNA_AVAILABLE",
]
Loading
Loading