@integrity-labs/cloud-broker 0.6.0 → 0.6.2
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/dist/index.js +36 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -21126,6 +21126,23 @@ var BrokerClient = class {
|
|
|
21126
21126
|
pollGrant(args) {
|
|
21127
21127
|
return this.request("GET", `/aws/grants/${encodeURIComponent(args.grant_id)}`);
|
|
21128
21128
|
}
|
|
21129
|
+
/**
|
|
21130
|
+
* ENG-4824: pre-flight check that the agent's Slack bot can actually
|
|
21131
|
+
* post to the AWS-approval channel configured for an enrolment. Mirror
|
|
21132
|
+
* of describeScope's GET-with-agent_id pattern — the API derives the
|
|
21133
|
+
* enrolment row and the agent's bot token server-side, calls Slack,
|
|
21134
|
+
* and returns the same shape as slack.channel_info.
|
|
21135
|
+
*/
|
|
21136
|
+
checkApprovalChannel(args) {
|
|
21137
|
+
if (!this.agentId) {
|
|
21138
|
+
throw makeBrokerError(400, "BrokerClient.checkApprovalChannel requires agentId \u2014 pass it in BrokerClientConfig");
|
|
21139
|
+
}
|
|
21140
|
+
return this.request(
|
|
21141
|
+
"GET",
|
|
21142
|
+
"/aws/approval-channel-status",
|
|
21143
|
+
{ query: { account_id: args.account_id, agent_id: this.agentId } }
|
|
21144
|
+
);
|
|
21145
|
+
}
|
|
21129
21146
|
releaseAccess(args) {
|
|
21130
21147
|
return this.request(
|
|
21131
21148
|
"POST",
|
|
@@ -21204,17 +21221,21 @@ var releaseAccessSchema = external_exports.object({
|
|
|
21204
21221
|
var getCredentialsSchema = external_exports.object({
|
|
21205
21222
|
grant_id: external_exports.string().uuid("grant_id must be a UUID")
|
|
21206
21223
|
});
|
|
21224
|
+
var checkApprovalChannelSchema = external_exports.object({
|
|
21225
|
+
account_id: accountIdSchema
|
|
21226
|
+
});
|
|
21207
21227
|
var describeScopeShape = describeScopeSchema.shape;
|
|
21208
21228
|
var previewRequestShape = previewRequestSchema.shape;
|
|
21209
21229
|
var requestAccessShape = requestAccessSchema.shape;
|
|
21210
21230
|
var pollGrantShape = pollGrantSchema.shape;
|
|
21211
21231
|
var releaseAccessShape = releaseAccessSchema.shape;
|
|
21212
21232
|
var getCredentialsShape = getCredentialsSchema.shape;
|
|
21233
|
+
var checkApprovalChannelShape = checkApprovalChannelSchema.shape;
|
|
21213
21234
|
|
|
21214
21235
|
// package.json
|
|
21215
21236
|
var package_default = {
|
|
21216
21237
|
name: "@integrity-labs/cloud-broker",
|
|
21217
|
-
version: "0.6.
|
|
21238
|
+
version: "0.6.2",
|
|
21218
21239
|
description: "Cloud Access Broker \u2014 MCP server that mints scoped, TTL-bounded cloud credentials per agent task. v1 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.",
|
|
21219
21240
|
type: "module",
|
|
21220
21241
|
bin: {
|
|
@@ -21319,9 +21340,22 @@ server.tool(
|
|
|
21319
21340
|
}
|
|
21320
21341
|
}
|
|
21321
21342
|
);
|
|
21343
|
+
server.tool(
|
|
21344
|
+
"aws_check_approval_channel",
|
|
21345
|
+
`Verify the agent's Slack bot can post to the AWS-approval channel for an account BEFORE calling aws_request_access. Returns { ok, channel?, bot_user_handle?, reason? }. When ok=false, branch on reason: "channel_not_found" or "not_in_channel" \u2192 tell the user "I need to be invited to the approvals channel before I can request access \u2014 please run \`/invite @<bot_user_handle>\` in your AWS-approvals channel and let me know when done"; "archived" \u2192 tell the user the configured channel is archived and an admin needs to repoint it in Team Settings; "no_approval_channel_configured" \u2192 tell the user no approval channel is set up for this AWS account and ask them to configure one in Team Settings; "agent_slack_not_configured" \u2192 escalate to operator (you have no Slack bot at all, so /invite won't help); "auth_failed" or "unknown" \u2192 escalate to operator with raw_error. ALWAYS call this on the FIRST aws_request_access for a given account_id in a session \u2014 once you've gotten ok=true once, you can skip subsequent pre-checks. If ok=false, DO NOT call aws_request_access \u2014 surface the user-facing message above and wait. Same jargon-free, no-mechanics rules as aws_request_access: never expose "broker", "grant", "MCP", "Slack channel ID", etc to the user \u2014 talk about the AWS account and the invite action.`,
|
|
21346
|
+
checkApprovalChannelShape,
|
|
21347
|
+
async (args) => {
|
|
21348
|
+
try {
|
|
21349
|
+
const result = await broker.checkApprovalChannel(args);
|
|
21350
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
21351
|
+
} catch (err) {
|
|
21352
|
+
return { content: [{ type: "text", text: formatBrokerError(err) }], isError: true };
|
|
21353
|
+
}
|
|
21354
|
+
}
|
|
21355
|
+
);
|
|
21322
21356
|
server.tool(
|
|
21323
21357
|
"aws_request_access",
|
|
21324
|
-
'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). source_context is optional but you SHOULD pass it whenever the request was triggered by an inbound channel message: extract { channel_type, channel_id, thread_ts? } from the `<channel>` tag in the conversation that triggered this. Slack: channel_type="slack", channel_id=tag\'s `channel`, thread_ts=tag\'s `thread_ts`. Telegram: channel_type="telegram", channel_id=tag\'s `chat_id`. Direct-chat: channel_type="direct-chat", channel_id=tag\'s `session_id`. Without source_context the resolution notification dead-ends in your direct-chat instead of threading back to the original conversation. Returns { grant_id, status, secret_ref?, expires_at?, denial_reason?, notification_status?, notification_failure_reason? }. status="active" means credentials are ready, use them now. status="denied" means the request was rejected (denial_reason explains). status="pending" means approval is still outstanding \u2014 DO NOT poll.
|
|
21358
|
+
'Request scoped, TTL-bounded AWS credentials for the current task. CALL aws_check_approval_channel FIRST on the FIRST request for a given account_id in a session \u2014 if it returns ok=false, DO NOT call this tool, surface the invite-the-bot message instead. agent_id and run_id are optional \u2014 the broker fills them from the host MCP env (AGT_AGENT_ID / AGT_RUN_ID). source_context is optional but you SHOULD pass it whenever the request was triggered by an inbound channel message: extract { channel_type, channel_id, thread_ts? } from the `<channel>` tag in the conversation that triggered this. Slack: channel_type="slack", channel_id=tag\'s `channel`, thread_ts=tag\'s `thread_ts`. Telegram: channel_type="telegram", channel_id=tag\'s `chat_id`. Direct-chat: channel_type="direct-chat", channel_id=tag\'s `session_id`. Without source_context the resolution notification dead-ends in your direct-chat instead of threading back to the original conversation. Returns { grant_id, status, secret_ref?, expires_at?, denial_reason?, notification_status?, notification_failure_reason?, notification_channel_name?, notification_channel_id?, notification_permalink?, notification_bot_user_handle? }. status="active" means credentials are ready, use them now. status="denied" means the request was rejected (denial_reason explains). status="pending" means approval is still outstanding \u2014 DO NOT poll. Post a brief, jargon-free acknowledgement to the user first. When notification_channel_name is populated, QUOTE IT VERBATIM in the acknowledgement (e.g. "Requesting access to the <aws_account_name> account so I can <do the task> \u2014 pinged an admin in #<notification_channel_name> to approve, will resume the moment it lands"); NEVER invent or guess a channel name from training (e.g. "#aws-approvals" is wrong if the configured channel is "#agt-approvals"). When notification_permalink is populated, you MAY append it as a markdown link (e.g. "[approval card](<notification_permalink>)") so the user can jump straight to it; otherwise omit. When notification_channel_name is absent, fall back to the channel-agnostic phrasing ("pinged an admin to approve"). Then save the grant_id and return control. NEVER expose broker mechanics to the user \u2014 phrases like "firing a broker grant", "requesting a grant", "broker grant", "grant_id", "secret_ref", "STS", "AssumeRole", or any aws_* tool name must not appear in user-facing messages. Also NEVER paste the grant UUID into user-facing prose (e.g. "request c7a0b7be-5e09-\u2026 is queued") \u2014 it is operator-only metadata and reads as noise to the user. Talk about the task and the AWS account, not the plumbing. The broker pushes the resolution to you via direct-chat the moment a human approves or denies. The notification body will include an "Original conversation:" line naming the channel/thread to reply in \u2014 when it arrives, post a one-line acknowledgement there in the same jargon-free style ("Approval came through for <aws_account_name> \u2014 kicking off <the task> now" on active; "Couldn\'t get access to <aws_account_name> for <the task>: <paraphrased reason> \u2014 let me know how you\'d like to proceed" on denied) BEFORE calling aws_get_credentials or doing the work, then complete the user\'s task in that same channel/thread (not direct-chat). Going silent between the request and the work loses the human-in-the-loop signal. Only check notification_status if you need to flag a setup issue to the user: "sent" means a human was paged; "failed" or "not_attempted" means no human was paged (typically channel_not_found because the approval-bot is not a member of the configured channel). When notification_status is "failed" and notification_bot_user_handle + notification_channel_name are populated, name them specifically in the user message: "I queued the access request for <aws_account_name> but couldn\'t notify the approver \u2014 please run `/invite @<notification_bot_user_handle>` in #<notification_channel_name> and let me know when done so I can re-fire". When the handle/channel-name aren\'t populated, fall back to the generic version: "I couldn\'t reach an approver for the <aws_account_name> account (the approval bot isn\'t in the configured channel) \u2014 please ping an admin manually, or fix the AWS approval channel in Team Settings". Keep the user-facing text jargon-free and paraphrased. grant_id and notification_failure_reason are operator/escalation-only metadata; if and only if you are escalating to an operator, append "(reference: <grant_id>, failure: <notification_failure_reason>)" to the operator-facing escalation note. aws_poll_grant exists as an escape hatch for explicit re-checks but the autonomous flow does not need it.',
|
|
21325
21359
|
requestAccessShape,
|
|
21326
21360
|
async (args) => {
|
|
21327
21361
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@integrity-labs/cloud-broker",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "Cloud Access Broker — MCP server that mints scoped, TTL-bounded cloud credentials per agent task. v1 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": {
|