@integrity-labs/cloud-broker 0.2.2 → 0.4.3

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.
Files changed (2) hide show
  1. package/dist/index.js +51 -15
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20994,7 +20994,8 @@ function makeBrokerError(status, message, detail) {
20994
20994
  }
20995
20995
  var BrokerClient = class {
20996
20996
  host;
20997
- teamSlug;
20997
+ agentId;
20998
+ runId;
20998
20999
  apiKey;
20999
21000
  fetchImpl;
21000
21001
  token;
@@ -21002,7 +21003,8 @@ var BrokerClient = class {
21002
21003
  exchangeInFlight = null;
21003
21004
  constructor(config2) {
21004
21005
  this.host = config2.host.replace(/\/+$/, "");
21005
- this.teamSlug = config2.teamSlug;
21006
+ this.agentId = config2.agentId;
21007
+ this.runId = config2.runId;
21006
21008
  this.apiKey = config2.apiKey;
21007
21009
  this.fetchImpl = config2.fetchImpl ?? fetch;
21008
21010
  this.token = config2.initialToken ?? "";
@@ -21019,8 +21021,7 @@ var BrokerClient = class {
21019
21021
  buildHeaders(token, contentType = "application/json") {
21020
21022
  return {
21021
21023
  "Content-Type": contentType,
21022
- Authorization: `Bearer ${token}`,
21023
- "X-Team-Slug": this.teamSlug
21024
+ Authorization: `Bearer ${token}`
21024
21025
  };
21025
21026
  }
21026
21027
  async refreshToken() {
@@ -21089,21 +21090,38 @@ var BrokerClient = class {
21089
21090
  }
21090
21091
  // ────────────────────────── tool-shaped wrappers ──────────────────────────
21091
21092
  describeScope(args) {
21093
+ if (!this.agentId) {
21094
+ throw makeBrokerError(400, "BrokerClient.describeScope requires agentId \u2014 pass it in BrokerClientConfig");
21095
+ }
21092
21096
  return this.request(
21093
21097
  "GET",
21094
21098
  "/aws/scope",
21095
- { query: { account_id: args.account_id } }
21099
+ { query: { account_id: args.account_id, agent_id: this.agentId } }
21096
21100
  );
21097
21101
  }
21098
21102
  previewRequest(args) {
21103
+ if (!this.agentId) {
21104
+ throw makeBrokerError(400, "BrokerClient.previewRequest requires agentId \u2014 pass it in BrokerClientConfig");
21105
+ }
21106
+ const body = { ...args };
21107
+ if (body.agent_id === void 0) body.agent_id = this.agentId;
21099
21108
  return this.request(
21100
21109
  "POST",
21101
21110
  "/aws/scope/preview",
21102
- { body: args }
21111
+ { body }
21103
21112
  );
21104
21113
  }
21105
- requestAccess(args) {
21106
- return this.request("POST", "/aws/grants", { body: args });
21114
+ async requestAccess(args) {
21115
+ const agentId = args.agent_id ?? this.agentId;
21116
+ const runId = args.run_id ?? this.runId;
21117
+ if (!agentId) {
21118
+ throw makeBrokerError(400, "BrokerClient.requestAccess requires agent_id (pass it in args, or set agentId on BrokerClientConfig)");
21119
+ }
21120
+ if (!runId) {
21121
+ throw makeBrokerError(400, "BrokerClient.requestAccess requires run_id (pass it in args, or set runId on BrokerClientConfig)");
21122
+ }
21123
+ const body = { ...args, agent_id: agentId, run_id: runId };
21124
+ return this.request("POST", "/aws/grants", { body });
21107
21125
  }
21108
21126
  pollGrant(args) {
21109
21127
  return this.request("GET", `/aws/grants/${encodeURIComponent(args.grant_id)}`);
@@ -21133,8 +21151,16 @@ var previewRequestSchema = external_exports.object({
21133
21151
  ttl_seconds: ttlSecondsSchema
21134
21152
  });
21135
21153
  var requestAccessSchema = external_exports.object({
21136
- agent_id: external_exports.string().uuid("agent_id must be a UUID"),
21137
- run_id: external_exports.string().uuid("run_id must be a UUID"),
21154
+ // ENG-4746: agent_id and run_id are optional. The MCP server fills them
21155
+ // from AGT_AGENT_ID / AGT_RUN_ID env at provision time, so the agent
21156
+ // doesn't need to know its own UUID. Pass them explicitly only to
21157
+ // attribute the grant to a different agent or run (e.g. delegated work).
21158
+ agent_id: external_exports.string().uuid("agent_id must be a UUID").optional().describe(
21159
+ "Optional. Defaults to the host MCP env (AGT_AGENT_ID). Pass explicitly only to attribute the grant to a different agent."
21160
+ ),
21161
+ run_id: external_exports.string().uuid("run_id must be a UUID").optional().describe(
21162
+ "Optional. Defaults to the host MCP env (AGT_RUN_ID). Pass explicitly only to attribute the grant to a different run."
21163
+ ),
21138
21164
  account_id: accountIdSchema,
21139
21165
  actions: actionListSchema,
21140
21166
  resources: resourceListSchema,
@@ -21159,18 +21185,28 @@ var releaseAccessShape = releaseAccessSchema.shape;
21159
21185
 
21160
21186
  // src/index.ts
21161
21187
  var AGT_HOST = process.env.AGT_HOST;
21162
- var AGT_TEAM_SLUG = process.env.AGT_TEAM_SLUG;
21188
+ var AGT_AGENT_ID = process.env.AGT_AGENT_ID;
21189
+ var AGT_RUN_ID = process.env.AGT_RUN_ID ?? "";
21163
21190
  var AGT_TOKEN = process.env.AGT_TOKEN ?? "";
21164
21191
  var AGT_API_KEY = process.env.AGT_API_KEY ?? "";
21165
- if (!AGT_HOST || !AGT_TEAM_SLUG || !AGT_TOKEN && !AGT_API_KEY) {
21192
+ if (!AGT_HOST || !AGT_AGENT_ID || !AGT_TOKEN && !AGT_API_KEY) {
21166
21193
  console.error(
21167
- "cloud-broker: missing env vars. Need AGT_HOST, AGT_TEAM_SLUG, and one of AGT_TOKEN or AGT_API_KEY."
21194
+ "cloud-broker: missing env vars. Need AGT_HOST, AGT_AGENT_ID, and one of AGT_TOKEN or AGT_API_KEY."
21168
21195
  );
21169
21196
  process.exit(1);
21170
21197
  }
21198
+ if (process.env.AGT_TEAM_SLUG) {
21199
+ console.error(
21200
+ "cloud-broker: AGT_TEAM_SLUG is set but no longer required (the API derives team from agent_id). Safe to remove from .mcp.json env block."
21201
+ );
21202
+ }
21171
21203
  var broker = new BrokerClient({
21172
21204
  host: AGT_HOST,
21173
- teamSlug: AGT_TEAM_SLUG,
21205
+ agentId: AGT_AGENT_ID,
21206
+ // ENG-4746: thread AGT_RUN_ID through so request_access can default it.
21207
+ // Empty string is treated as absent — the broker client only fills runId
21208
+ // on requestAccess if a non-empty value is provided.
21209
+ runId: AGT_RUN_ID || void 0,
21174
21210
  initialToken: AGT_TOKEN || void 0,
21175
21211
  apiKey: AGT_API_KEY || void 0
21176
21212
  });
@@ -21213,7 +21249,7 @@ server.tool(
21213
21249
  );
21214
21250
  server.tool(
21215
21251
  "request_access",
21216
- 'Request scoped, TTL-bounded AWS credentials for the current task. Returns { grant_id, status, secret_ref?, expires_at?, denial_reason? }. status="active" means credentials are ready; status="pending" means a human approver was paged and you should poll_grant; status="denied" means the request was rejected (denial_reason explains).',
21252
+ 'Request scoped, TTL-bounded AWS credentials for the current task. agent_id and run_id are optional \u2014 the broker fills them from the host MCP env (AGT_AGENT_ID / AGT_RUN_ID). Only pass them explicitly to attribute the grant to a different agent or run. Returns { grant_id, status, secret_ref?, expires_at?, denial_reason?, notification_status?, notification_failure_reason? }. status="active" means credentials are ready; status="denied" means the request was rejected (denial_reason explains). status="pending" means approval is still outstanding \u2014 always check notification_status before deciding what to do next: "sent" means the Slack approval message reached the configured channel and poll_grant is appropriate; "failed" means the notification did NOT reach a human (typically channel_not_found because the bot is not a member of the approval channel) \u2014 quote grant_id + notification_failure_reason and recommend manual escalation instead of silently polling.',
21217
21253
  requestAccessShape,
21218
21254
  async (args) => {
21219
21255
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/cloud-broker",
3
- "version": "0.2.2",
3
+ "version": "0.4.3",
4
4
  "description": "Cloud Access Broker — MCP server that mints scoped, TTL-bounded cloud credentials per agent task. v1 ships AWS support (request_access, poll_grant, release_access, describe_scope, preview_request — 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": {