@integrity-labs/cloud-broker 0.7.3 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/dist/index.js +30 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,23 @@ See the PRDs ([AWS](../../docs/prds/aws-ephemeral-access.md), [GCP](../../docs/p
|
|
|
37
37
|
| `gcp_check_approval_channel` | Pre-flight Slack channel reachability for the project's approval channel. |
|
|
38
38
|
| `gcp_list_accounts` | Live inventory of enrolled GCP projects. |
|
|
39
39
|
|
|
40
|
+
### Supabase
|
|
41
|
+
|
|
42
|
+
Credentials returned are a short-lived **Supabase JWT** (+ `supabase_url`, `db_host`, `project_ref`), not a cloud IAM token. The agent uses it for PostgREST (`Authorization: Bearer …`) or `psql` via the session pooler.
|
|
43
|
+
|
|
44
|
+
| Tool | Purpose |
|
|
45
|
+
|---|---|
|
|
46
|
+
| `supabase_describe_scope` | Resolved policy ceiling for a Supabase project (auto-approvable roles, schema ceiling, write gating). Free, idempotent. |
|
|
47
|
+
| `supabase_preview_request` | Dry-run a candidate request. Writes nothing. |
|
|
48
|
+
| `supabase_request_access` | Mint or queue a grant. `service_role` always routes to a human approver; privileged internal roles (`postgres`, `supabase_admin`, …) are hard-denied. |
|
|
49
|
+
| `supabase_poll_grant` | Single-shot status check. Escape hatch. |
|
|
50
|
+
| `supabase_get_credentials` | Fetch the JWT + connection details for an active grant. |
|
|
51
|
+
| `supabase_release_access` | Voluntarily release a grant before TTL. Idempotent. **Note:** the JWT is stateless — release marks the grant revoked but the token stays valid until its `exp`. |
|
|
52
|
+
| `supabase_check_approval_channel` | Pre-flight Slack channel reachability for the project's approval channel. |
|
|
53
|
+
| `supabase_list_projects` | Live inventory of enrolled Supabase projects. |
|
|
54
|
+
|
|
55
|
+
See **[`docs/runbooks/supabase-broker-enrollment.md`](../../docs/runbooks/supabase-broker-enrollment.md)** for operator enrollment, the `augmented` JWT-claim → RLS-policy enforcement guide, and the policy-ceiling shape.
|
|
56
|
+
|
|
40
57
|
## Environment
|
|
41
58
|
|
|
42
59
|
| Var | Purpose |
|
|
@@ -134,6 +151,57 @@ gcp_release_access({ grant_id: "..." })
|
|
|
134
151
|
|
|
135
152
|
Same `pending` / direct-chat-push resolution semantics as AWS. The runtime resolves `secret_ref://gcp/runs/...` to `CLOUDSDK_AUTH_ACCESS_TOKEN` and `GOOGLE_OAUTH_ACCESS_TOKEN` at exec time, so `gcloud`, `gsutil`, and `bq` all pick it up automatically without the agent ever handling the raw token.
|
|
136
153
|
|
|
154
|
+
## Worked example (Supabase)
|
|
155
|
+
|
|
156
|
+
An agent that needs read-only access to two tables in `public`:
|
|
157
|
+
|
|
158
|
+
```jsonc
|
|
159
|
+
// 1. Inspect the envelope — which roles auto-approve, the schema ceiling, write gating.
|
|
160
|
+
supabase_describe_scope({ project_ref: "abcdefghijklmnopqrst" })
|
|
161
|
+
|
|
162
|
+
// 2. Dry-run.
|
|
163
|
+
supabase_preview_request({
|
|
164
|
+
project_ref: "abcdefghijklmnopqrst",
|
|
165
|
+
role: "authenticated",
|
|
166
|
+
allowed_schemas: ["public"],
|
|
167
|
+
allowed_tables: ["public.agents", "public.runs"], // optional — absent = all tables in allowed_schemas
|
|
168
|
+
read_only: true,
|
|
169
|
+
ttl_seconds: 900
|
|
170
|
+
})
|
|
171
|
+
// → { "would": "auto_approve", "reason": null }
|
|
172
|
+
|
|
173
|
+
// 3. Mint.
|
|
174
|
+
supabase_request_access({
|
|
175
|
+
project_ref: "abcdefghijklmnopqrst",
|
|
176
|
+
role: "authenticated",
|
|
177
|
+
allowed_schemas: ["public"],
|
|
178
|
+
allowed_tables: ["public.agents", "public.runs"],
|
|
179
|
+
read_only: true,
|
|
180
|
+
ttl_seconds: 900,
|
|
181
|
+
reason: "read the agents + runs tables to answer the user's status question"
|
|
182
|
+
})
|
|
183
|
+
// → { "grant_id": "...", "status": "active", "secret_ref": "supabase:jwt:<grant_id>", "expires_at": "..." }
|
|
184
|
+
// `service_role` or write access (read_only:false, unless the project allows writes)
|
|
185
|
+
// returns "pending" instead and pages a human approver.
|
|
186
|
+
|
|
187
|
+
// 4. Fetch the JWT + connection details.
|
|
188
|
+
supabase_get_credentials({ grant_id: "..." })
|
|
189
|
+
// → { "grant_id": "...", "expires_at": "...",
|
|
190
|
+
// "credentials": { "access_token": "<JWT>", "supabase_url": "https://<ref>.supabase.co",
|
|
191
|
+
// "db_host": "aws-0-<region>.pooler.supabase.com", "project_ref": "<ref>" } }
|
|
192
|
+
//
|
|
193
|
+
// REST (PostgREST):
|
|
194
|
+
// curl "$supabase_url/rest/v1/agents?select=*" \
|
|
195
|
+
// -H "apikey: <JWT>" -H "Authorization: Bearer <JWT>"
|
|
196
|
+
// psql (session pooler):
|
|
197
|
+
// psql "postgresql://postgres.<project_ref>:<JWT>@<db_host>:5432/postgres"
|
|
198
|
+
|
|
199
|
+
// 5. (Optional) release early.
|
|
200
|
+
supabase_release_access({ grant_id: "..." })
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The grant's scope (`allowed_schemas` / `allowed_tables` / `read_only`) is carried in the JWT's `augmented` claim and is **only enforced if the project's RLS policies read that claim** — see the [enrollment runbook](../../docs/runbooks/supabase-broker-enrollment.md#enforcing-the-grant-scope-with-rls) for the policy patterns. Same `pending` / direct-chat-push resolution semantics as AWS.
|
|
204
|
+
|
|
137
205
|
## Running locally
|
|
138
206
|
|
|
139
207
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -20985,6 +20985,26 @@ var StdioServerTransport = class {
|
|
|
20985
20985
|
}
|
|
20986
20986
|
};
|
|
20987
20987
|
|
|
20988
|
+
// src/turn-initiator-marker.ts
|
|
20989
|
+
import { readFileSync } from "fs";
|
|
20990
|
+
var TURN_INITIATOR_MAX_AGE_MS = 5 * 60 * 1e3;
|
|
20991
|
+
function readTurnInitiator(maxAgeMs = TURN_INITIATOR_MAX_AGE_MS) {
|
|
20992
|
+
const file = process.env["AGT_TURN_INITIATOR_FILE"];
|
|
20993
|
+
if (!file) return null;
|
|
20994
|
+
try {
|
|
20995
|
+
const raw = readFileSync(file, "utf8");
|
|
20996
|
+
const m = JSON.parse(raw);
|
|
20997
|
+
if (typeof m.channel !== "string" || !m.channel) return null;
|
|
20998
|
+
if (typeof m.sender_id !== "string" || !m.sender_id) return null;
|
|
20999
|
+
if (typeof m.ts !== "number" || !Number.isFinite(m.ts)) return null;
|
|
21000
|
+
const age = Date.now() - m.ts;
|
|
21001
|
+
if (age < 0 || age > maxAgeMs) return null;
|
|
21002
|
+
return { channel: m.channel, sender_id: m.sender_id };
|
|
21003
|
+
} catch {
|
|
21004
|
+
return null;
|
|
21005
|
+
}
|
|
21006
|
+
}
|
|
21007
|
+
|
|
20988
21008
|
// src/broker-client.ts
|
|
20989
21009
|
function makeBrokerError(status, message, detail) {
|
|
20990
21010
|
const err = new Error(message);
|
|
@@ -21123,7 +21143,15 @@ var BrokerClient = class {
|
|
|
21123
21143
|
if (!runId) {
|
|
21124
21144
|
throw makeBrokerError(400, "BrokerClient.requestAccess requires run_id (pass it in args, or set runId on BrokerClientConfig)");
|
|
21125
21145
|
}
|
|
21126
|
-
const
|
|
21146
|
+
const turnInitiator = readTurnInitiator();
|
|
21147
|
+
const { turn_initiator: _ignoredForged, ...safeArgs } = args;
|
|
21148
|
+
void _ignoredForged;
|
|
21149
|
+
const body = {
|
|
21150
|
+
...safeArgs,
|
|
21151
|
+
agent_id: agentId,
|
|
21152
|
+
run_id: runId,
|
|
21153
|
+
...turnInitiator ? { turn_initiator: turnInitiator } : {}
|
|
21154
|
+
};
|
|
21127
21155
|
return this.request("POST", `${this.apiPathPrefix}/grants`, { body });
|
|
21128
21156
|
}
|
|
21129
21157
|
pollGrant(args) {
|
|
@@ -21574,7 +21602,7 @@ var supabaseListProjectsShape = supabaseListProjectsSchema.shape;
|
|
|
21574
21602
|
// package.json
|
|
21575
21603
|
var package_default = {
|
|
21576
21604
|
name: "@integrity-labs/cloud-broker",
|
|
21577
|
-
version: "0.7.
|
|
21605
|
+
version: "0.7.5",
|
|
21578
21606
|
description: "Cloud Access Broker \u2014 MCP server that mints scoped, TTL-bounded cloud credentials per agent task. Ships AWS support (aws_request_access, aws_poll_grant, aws_release_access, aws_describe_scope, aws_preview_request, aws_get_credentials \u2014 STS AssumeRole under the hood); GCP, Azure, and Cloudflare land alongside in the same package as the broker grows.",
|
|
21579
21607
|
type: "module",
|
|
21580
21608
|
bin: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@integrity-labs/cloud-broker",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "Cloud Access Broker — MCP server that mints scoped, TTL-bounded cloud credentials per agent task. Ships AWS support (aws_request_access, aws_poll_grant, aws_release_access, aws_describe_scope, aws_preview_request, aws_get_credentials — STS AssumeRole under the hood); GCP, Azure, and Cloudflare land alongside in the same package as the broker grows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|