Skip to content

Commit b74fbfc

Browse files
authored
Merge pull request #73 from Prescott-Data/feat/doc-site-update
Feat/doc site update
2 parents 68c4fbd + ef9c8a4 commit b74fbfc

41 files changed

Lines changed: 6005 additions & 720 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/CHANGELOG.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
---
2+
icon: material/history
3+
hide:
4+
- toc
5+
---
6+
7+
# Changelog
8+
9+
All notable changes to Nexus are documented here. This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
10+
11+
---
12+
13+
<div class="changelog-release" markdown>
14+
15+
## Unreleased <span class="changelog-date">2026-05-14</span>
16+
17+
<div class="changelog-meta" markdown>
18+
<div class="changelog-contributors">
19+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
20+
<a href="https://github.com/ekizito96" title="Muyukani Ephraim Kizito"><img src="https://github.com/ekizito96.png?size=32" alt="ekizito96"></a>
21+
</div>
22+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/commits/main" target="_blank" rel="noopener noreferrer">View commits on GitHub →</a>
23+
</div>
24+
25+
**Added**
26+
27+
- **Python SDK** (`nexus-sdk-python`): full-feature-parity Python client — `get_token_by_connection_id`, `resolve_token`, `request_connection`, `check_connection`. Zero external dependencies.
28+
- **TypeScript SDK** (`@dromos/nexus-sdk`): evolved from `nexus-mcp-adapter`. MCP token resolution, in-memory caching, authenticated transport, and `resolveToken` for stateless MCP clients. Built to `dist/`, ESM imports hardened.
29+
- **Go SDK MCP integration**: `ResolveToken` endpoint for stateless MCP clients — workspace and provider-scoped token resolution with TTL caching.
30+
- **Multi-strategy credential support** across all three SDKs: handles `oauth2`, `api_key`, `basic_auth`, `aws_sigv4`, `query_param`, and `hmac_payload` strategies without caller-side branching.
31+
- **Automated release workflow**: GitHub Actions CI/CD pipeline, bumped `VERSION` to `0.2.3`.
32+
- **Agent auth proposal** (`AGENT_AUTH_PROPOSAL.md`): full design document for agent identity, OBO sessions, scoped session TTLs, and custom scope enforcement.
33+
- **SDK documentation**: comprehensive reference pages for Go, TypeScript, and Python SDKs including install, method signatures, MCP integration examples, and error handling.
34+
35+
**Fixed**
36+
37+
- TypeScript SDK: `Bearer` token type normalized to RFC 6750 capitalization (was `bearer`).
38+
- TypeScript SDK: package entry pointed at compiled `dist/`, not `.ts` source.
39+
- Gateway: `resolve` route wired; ESM import errors resolved in adapter.
40+
- Adapter/Gateway: token TTL hardened, stdio safety improved, error handling tightened.
41+
- MCP adapter smoke test added against live Gateway.
42+
43+
</div>
44+
45+
---
46+
47+
<div class="changelog-release" markdown>
48+
49+
## 0.2.0 <span class="changelog-date">2026-05-05</span>
50+
51+
<div class="changelog-meta" markdown>
52+
<div class="changelog-contributors">
53+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
54+
<a href="https://github.com/Abdullahi254" title="Abdullahi Mohamud"><img src="https://github.com/Abdullahi254.png?size=32" alt="Abdullahi254"></a>
55+
</div>
56+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.2.0" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
57+
</div>
58+
59+
**Added**
60+
61+
- **Security-as-Code CLI** (`nexus-cli`): Terraform-style `plan → confirm → apply` workflow for declarative provider management via YAML manifest. PATCH-based reconciliation (no accidental overwrites), concurrent profile fetching with bounded worker pool, field-level diff output with secret masking, fail-fast on unresolved env vars, non-zero exit on partial apply failure.
62+
- **Audit subsystem** (`audit.Service`): structured event logging to `audit_events` table with IP validation, User-Agent capture, and `audit.Logger` interface for test mocking. Events: `provider.created`, `provider.updated`, `provider.deleted`, `connection.created`, `token.retrieved`, `token.refresh_fatal`.
63+
- **`GET /audit` endpoint**: queryable audit log with `event_type`, `resource_id`, `since`, `until`, `limit`, and `offset` filters.
64+
- **Credential redaction**: `PATCH` audit payloads redact `client_secret` and `client_id` before writing to the audit log.
65+
- **Provider `category` field**: `category` added to provider profiles with migration. Gateway `MetadataResponse` patched to include `category` in the OpenAPI-generated response.
66+
- **`capture-schema` and `capture-credential` endpoints**: Gateway proxies for static credential capture flow, enabling API key and basic auth connections without OAuth redirects.
67+
68+
**Fixed**
69+
70+
- Gateway: manually patched `MetadataResponse` to include `category` field, avoiding `oapi-codegen` version mismatch.
71+
- Documentation: all examples standardized to `localhost:8090` — internal Azure URLs removed.
72+
- OpenAPI: `description` and `category` added to `MetadataResponse` and `ProviderProfile` schemas; gateway broker client regenerated.
73+
74+
</div>
75+
76+
---
77+
78+
<div class="changelog-release" markdown>
79+
80+
## 0.1.5 <span class="changelog-date">2026-04-13</span>
81+
82+
<div class="changelog-meta" markdown>
83+
<div class="changelog-contributors">
84+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
85+
<a href="https://github.com/ashioyajotham" title="Victor Ashioya"><img src="https://github.com/ashioyajotham.png?size=32" alt="ashioyajotham"></a>
86+
</div>
87+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.1.5" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
88+
</div>
89+
90+
**Changed**
91+
92+
- Bridge: replaced `goto Retry` with `for`-loop in `MaintainGRPCConnection` — cleaner control flow, no goto jumps. ([@ashioyajotham](https://github.com/ashioyajotham))
93+
- Broker: replaced streaming `json.Encoder` with marshal-then-write pattern — eliminates partial-write race on slow connections. ([@ashioyajotham](https://github.com/ashioyajotham))
94+
- Security documentation hardened: shared secrets, key rotation, and deployment guidance expanded.
95+
96+
**Fixed**
97+
98+
- Broker: handle SQL `NULL` values for non-OAuth2 provider profiles — `api_key` and `basic_auth` providers no longer cause null pointer panics in the profile store.
99+
100+
</div>
101+
102+
---
103+
104+
<div class="changelog-release" markdown>
105+
106+
## 0.1.4 <span class="changelog-date">2026-04-01</span>
107+
108+
<div class="changelog-meta" markdown>
109+
<div class="changelog-contributors">
110+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
111+
</div>
112+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.1.4" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
113+
</div>
114+
115+
**Added**
116+
117+
- Broker: `skip_scope_on_auth` provider parameter — bypasses strict scope validation on the authorization URL for providers that reject scope in the initial redirect (Salesforce).
118+
119+
</div>
120+
121+
---
122+
123+
<div class="changelog-release" markdown>
124+
125+
## 0.1.3 <span class="changelog-date">2026-04-01</span>
126+
127+
<div class="changelog-meta" markdown>
128+
<div class="changelog-contributors">
129+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
130+
<a href="https://github.com/ashioyajotham" title="Victor Ashioya"><img src="https://github.com/ashioyajotham.png?size=32" alt="ashioyajotham"></a>
131+
</div>
132+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.1.3" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
133+
</div>
134+
135+
**Added**
136+
137+
- Broker: validate `api_key` and `basic_auth` credentials before storing — rejects malformed or empty credentials at capture time rather than at retrieval.
138+
139+
**Fixed**
140+
141+
- Broker: enforce one token row per connection via upsert — eliminates duplicate token rows on reconnect. ([@ashioyajotham](https://github.com/ashioyajotham))
142+
- Security: `ENCRYPTION_KEY` and `STATE_KEY` are now required at startup — Broker and Gateway fatal-exit with a clear message if either is absent. ([@ashioyajotham](https://github.com/ashioyajotham))
143+
- Tests: `TestMain` used for binary lifecycle management; assertions refined.
144+
- Gateway: `gofmt` formatting applied to main files.
145+
146+
</div>
147+
148+
---
149+
150+
<div class="changelog-release" markdown>
151+
152+
## 0.1.2 <span class="changelog-date">2026-04-01</span>
153+
154+
<div class="changelog-meta" markdown>
155+
<div class="changelog-contributors">
156+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
157+
</div>
158+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.1.2" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
159+
</div>
160+
161+
**Fixed**
162+
163+
- Docker: corrected image names to `nexus-broker` and `nexus-gateway` — was using incorrect names that broke `docker pull` and Compose service references.
164+
165+
</div>
166+
167+
---
168+
169+
<div class="changelog-release" markdown>
170+
171+
## 0.1.1 <span class="changelog-date">2026-04-01</span>
172+
173+
<div class="changelog-meta" markdown>
174+
<div class="changelog-contributors">
175+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
176+
<a href="https://github.com/Abdullahi254" title="Abdullahi Mohamud"><img src="https://github.com/Abdullahi254.png?size=32" alt="Abdullahi254"></a>
177+
</div>
178+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.1.1" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
179+
</div>
180+
181+
**Added**
182+
183+
- Docker Hub publishing GitHub Actions workflow.
184+
- Gateway: `capture-schema` and `capture-credential` proxy endpoints for static credential flows. ([@Abdullahi254](https://github.com/Abdullahi254))
185+
- Open-core refactor: internal packages made public to support the OSS consumption model.
186+
187+
**Fixed**
188+
189+
- Go module paths updated to `github.com/Prescott-Data/nexus-framework` throughout.
190+
- Broken database migration corrected.
191+
192+
</div>
193+
194+
---
195+
196+
<div class="changelog-release" markdown>
197+
198+
## 0.1.0 <span class="changelog-date">2026-02-19</span>
199+
200+
<div class="changelog-meta" markdown>
201+
<div class="changelog-contributors">
202+
<a href="https://github.com/sangalo20" title="Sangalo Mwenyinyo"><img src="https://github.com/sangalo20.png?size=32" alt="sangalo20"></a>
203+
</div>
204+
<a class="changelog-release-link" href="https://github.com/Prescott-Data/nexus-framework/releases/tag/v0.1.0" target="_blank" rel="noopener noreferrer">View release on GitHub →</a>
205+
</div>
206+
207+
Initial public release.
208+
209+
**Added**
210+
211+
- **Nexus Broker**: OAuth 2.0 and OIDC connection management — token storage (AES-GCM 256-bit at rest), background refresh loop, OIDC discovery with JWKS caching, nonce/id_token verification, Prometheus metrics.
212+
- **Nexus Gateway**: public-facing API for agents and backends. Versioned at `/v1`. gRPC-first communication to Broker with REST fallback.
213+
- **Nexus Bridge**: Go library for embedding in agent processes — `MaintainWebSocket` and `MaintainGRPCConnection` with automatic credential injection, token refresh, exponential backoff reconnection, and Prometheus metrics.
214+
- **Go SDK** (`nexus-sdk`): zero-dependency HTTP client for the Gateway API.
215+
- **Provider support**: Google (OIDC discovery), Azure AD (common tenant), GitHub, Salesforce, and arbitrary OAuth2 providers with manual endpoint configuration.
216+
- **Security guardrails**: IP allowlisting (`ALLOWED_CIDRS`), allowed return domain validation, API key enforcement.
217+
- **Docker Compose**: single `make up` command runs Broker, Gateway, PostgreSQL, and Redis.
218+
- **Bitbucket Pipelines**: initial CI/CD configuration.
219+
220+
</div>

docs/assets/nexus-logo-black.png

244 KB
Loading

docs/assets/nexus-logo-blue.png

87.5 KB
Loading

docs/assets/nexus-logo-white.png

459 KB
Loading

docs/concepts/agent-identity.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
icon: material/badge-account-outline
3+
---
4+
5+
# Agent Identity
6+
7+
The base Nexus connection model is anonymous: any process that holds a `connection_id` can retrieve tokens from it. There is no record of which agent is which, what it is allowed to do, or how long its authorization should last.
8+
9+
The agent identity model adds agents as first-class principals. An agent has a registered identity, a declared set of allowed scopes, and requests short-lived scoped sessions rather than holding a connection token directly. This model is currently in development.
10+
11+
## The agent registry
12+
13+
Each agent is registered once by an administrator:
14+
15+
```bash
16+
curl -X POST https://your-gateway.example.com/admin/v1/agents \
17+
-H "X-API-Key: your-admin-api-key" \
18+
-H "Content-Type: application/json" \
19+
-d '{
20+
"agent_id": "crm-agent",
21+
"description": "Reads and updates customer records in Salesforce",
22+
"allowed_scopes": ["crm:contacts:read", "crm:contacts:write"]
23+
}'
24+
```
25+
26+
| Field | Description |
27+
|---|---|
28+
| `agent_id` | Stable identifier for this agent — used in session requests and audit records |
29+
| `description` | Human-readable label for the agent registry UI |
30+
| `allowed_scopes` | The complete set of scopes this agent is ever permitted to request |
31+
32+
The `allowed_scopes` list is the agent's authorization ceiling. An agent can request any subset of these scopes at session time, but can never request a scope that is not in this list.
33+
34+
## Agent sessions
35+
36+
An agent session is a short-lived, scoped credential grant. The agent requests a session specifying exactly which scopes it needs for the current operation:
37+
38+
```bash
39+
curl -X POST https://your-gateway.example.com/v1/agent-sessions \
40+
-H "X-API-Key: your-gateway-api-key" \
41+
-H "Content-Type: application/json" \
42+
-d '{
43+
"agent_id": "crm-agent",
44+
"provider_name": "salesforce",
45+
"scopes": ["crm:contacts:read"],
46+
"ttl_seconds": 900
47+
}'
48+
```
49+
50+
Response:
51+
52+
```json
53+
{
54+
"session_id": "sess_a1b2c3",
55+
"access_token": "eyJ...",
56+
"scopes_granted": ["crm:contacts:read"],
57+
"expires_at": "2026-05-12T21:00:00Z"
58+
}
59+
```
60+
61+
The Broker enforces two constraints before issuing a session:
62+
63+
1. Every requested scope must be in the agent's `allowed_scopes` list.
64+
2. The agent's `allowed_scopes` are themselves a subset of what the underlying connection's provider grants.
65+
66+
If either check fails, the Broker returns `403`. The agent receives exactly what it requests — never more.
67+
68+
## Session lifecycle
69+
70+
| Field | Description |
71+
|---|---|
72+
| `session_id` | Stable identifier — use for audit queries and session closure |
73+
| `access_token` | Short-lived token to use against the provider's API |
74+
| `scopes_granted` | The actual scopes issued — confirm these match what you requested |
75+
| `expires_at` | Hard expiry — the session cannot be refreshed, only replaced |
76+
77+
When the agent finishes its operation, close the session explicitly:
78+
79+
```bash
80+
curl -X DELETE https://your-gateway.example.com/v1/agent-sessions/sess_a1b2c3 \
81+
-H "X-API-Key: your-gateway-api-key"
82+
```
83+
84+
Closing a session revokes the token server-side. A token intercepted after session closure cannot be replayed.
85+
86+
Sessions that are not explicitly closed expire at `expires_at`. The default TTL is 900 seconds (15 minutes).
87+
88+
## Custom scopes
89+
90+
Not every permission maps to an OAuth provider scope. Internal business operations have their own authorization requirements: `acme:gliding`, `acme:flaring`, `pipeline:trigger`, `reports:generate`. These are custom scopes.
91+
92+
Custom scopes are declared in the agent's `allowed_scopes` list exactly like provider scopes:
93+
94+
```bash
95+
curl -X POST https://your-gateway.example.com/admin/v1/agents \
96+
-H "X-API-Key: your-admin-api-key" \
97+
-d '{
98+
"agent_id": "ops-agent",
99+
"description": "Performs authorized internal financial operations",
100+
"allowed_scopes": [
101+
"acme:gliding",
102+
"acme:flaring",
103+
"crm:contacts:read"
104+
]
105+
}'
106+
```
107+
108+
The enforcement mechanism differs from provider scopes:
109+
110+
| Scope type | How the Broker resolves the session token |
111+
|---|---|
112+
| Provider scope (`crm:contacts:read`) | Fetches the underlying OAuth token from the stored connection, returns it scoped to the requested permissions |
113+
| Custom scope (`acme:gliding`) | Returns a signed session token asserting the agent is authorized for this scope — your downstream service validates the assertion |
114+
115+
For custom scopes, the session response includes `token_type: session` rather than `token_type: bearer`:
116+
117+
```json
118+
{
119+
"session_id": "sess_xyz",
120+
"session_token": "eyJ...",
121+
"scopes_granted": ["acme:gliding"],
122+
"expires_at": "2026-05-12T21:00:00Z",
123+
"token_type": "session"
124+
}
125+
```
126+
127+
Your downstream service verifies this session token against the Broker's public key, or by calling `GET /v1/agent-sessions/{session_id}` to confirm it is active.
128+
129+
## Why this matters
130+
131+
The connection model does not restrict what an agent can do with a token it retrieves. If the token has `crm:delete` scope, any agent with the `connection_id` can delete records. There is no enforcement point between the token's capabilities and the specific agent's intended use.
132+
133+
The agent identity model enforces least-privilege at the session layer. The `crm-agent` registered with `["crm:contacts:read"]` cannot request `crm:delete` even if the underlying Salesforce connection has it. The agent can only ever operate within its declared scope boundary, regardless of how the connection was authorized.
134+
135+
This is the difference between "the token allows this" and "this agent is allowed to do this."

0 commit comments

Comments
 (0)