edgegate-mcp 0.7.0 → 0.9.0
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 +7 -1
- package/dist/client.d.ts +19 -1
- package/dist/client.js +34 -0
- package/dist/client.js.map +1 -1
- package/dist/server.js +64 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/check_byo_bucket.d.ts +12 -0
- package/dist/tools/check_byo_bucket.js +89 -0
- package/dist/tools/check_byo_bucket.js.map +1 -0
- package/dist/tools/check_status.d.ts +2 -2
- package/dist/tools/check_status.js +6 -1
- package/dist/tools/check_status.js.map +1 -1
- package/dist/tools/compare_runs.d.ts +2 -2
- package/dist/tools/create_pipeline.d.ts +4 -4
- package/dist/tools/disconnect_byo_bucket.d.ts +12 -0
- package/dist/tools/disconnect_byo_bucket.js +90 -0
- package/dist/tools/disconnect_byo_bucket.js.map +1 -0
- package/dist/tools/export_run_report.d.ts +2 -2
- package/dist/tools/export_run_report.js +4 -1
- package/dist/tools/export_run_report.js.map +1 -1
- package/dist/tools/get_audit_report.d.ts +2 -2
- package/dist/tools/get_audit_report.js +5 -1
- package/dist/tools/get_audit_report.js.map +1 -1
- package/dist/tools/get_byo_audit.d.ts +27 -0
- package/dist/tools/get_byo_audit.js +125 -0
- package/dist/tools/get_byo_audit.js.map +1 -0
- package/dist/tools/get_report.d.ts +1 -1
- package/dist/tools/list_devices.d.ts +25 -0
- package/dist/tools/list_devices.js +81 -0
- package/dist/tools/list_devices.js.map +1 -0
- package/dist/tools/register_byo_artifact.d.ts +27 -0
- package/dist/tools/register_byo_artifact.js +122 -0
- package/dist/tools/register_byo_artifact.js.map +1 -0
- package/dist/tools/register_byo_bucket.d.ts +24 -0
- package/dist/tools/register_byo_bucket.js +143 -0
- package/dist/tools/register_byo_bucket.js.map +1 -0
- package/dist/types.d.ts +98 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/plugin.json +3 -2
- package/skills/edgegate-byo-storage.md +148 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { EdgeGateError } from "../client.js";
|
|
3
|
+
export const registerByoBucketInputSchema = z.object({
|
|
4
|
+
workspace_id: z.string().uuid(),
|
|
5
|
+
role_arn: z
|
|
6
|
+
.string()
|
|
7
|
+
.regex(/^arn:aws:iam::\d{12}:role\/.+$/)
|
|
8
|
+
.describe("ARN of the IAM role EdgeGate's workers will assume to read your bucket. " +
|
|
9
|
+
"Created by the EdgeGate CloudFormation launch stack (or your equivalent " +
|
|
10
|
+
"Terraform module). Format: arn:aws:iam::<account-id>:role/<name>."),
|
|
11
|
+
bucket: z
|
|
12
|
+
.string()
|
|
13
|
+
.min(3)
|
|
14
|
+
.max(255)
|
|
15
|
+
.regex(/^[a-z0-9][a-z0-9\-.]{1,253}$/)
|
|
16
|
+
.describe("S3 bucket name (not the URI — just the bucket name)."),
|
|
17
|
+
region: z
|
|
18
|
+
.string()
|
|
19
|
+
.min(4)
|
|
20
|
+
.max(64)
|
|
21
|
+
.describe("AWS region the bucket lives in, e.g. us-east-1."),
|
|
22
|
+
kms_key_id: z
|
|
23
|
+
.string()
|
|
24
|
+
.max(2048)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Optional KMS key ARN if the bucket uses SSE-KMS. The IAM role must " +
|
|
27
|
+
"have kms:Decrypt on this key."),
|
|
28
|
+
});
|
|
29
|
+
export async function registerByoBucketHandler(client, input) {
|
|
30
|
+
try {
|
|
31
|
+
const grant = await client.registerByoGrant(input.workspace_id, {
|
|
32
|
+
role_arn: input.role_arn,
|
|
33
|
+
bucket: input.bucket,
|
|
34
|
+
region: input.region,
|
|
35
|
+
kms_key_id: input.kms_key_id,
|
|
36
|
+
});
|
|
37
|
+
return successText(grant);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (err instanceof EdgeGateError) {
|
|
41
|
+
if (err.status === 402) {
|
|
42
|
+
return {
|
|
43
|
+
isError: true,
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: "text",
|
|
47
|
+
text: [
|
|
48
|
+
`BYO storage requires the **Enterprise plan**.`,
|
|
49
|
+
``,
|
|
50
|
+
`Reach out to sales at https://edgegate.frozo.ai/enterprise ` +
|
|
51
|
+
`to enable BYO storage on this workspace. ` +
|
|
52
|
+
`Once enabled, re-run \`edgegate_register_byo_bucket\` with the ` +
|
|
53
|
+
`same role + bucket details.`,
|
|
54
|
+
].join("\n"),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (err.status === 409) {
|
|
60
|
+
// Do NOT auto-rotate — the existing grant may belong to a different
|
|
61
|
+
// role_arn the customer doesn't want overwritten by accident.
|
|
62
|
+
return {
|
|
63
|
+
isError: true,
|
|
64
|
+
content: [
|
|
65
|
+
{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: [
|
|
68
|
+
`This workspace already has a BYO storage grant registered.`,
|
|
69
|
+
``,
|
|
70
|
+
`Two safe paths forward:`,
|
|
71
|
+
`1. Inspect the existing grant with \`edgegate_check_byo_bucket\` ` +
|
|
72
|
+
`to confirm it's the one you intended.`,
|
|
73
|
+
`2. If you want to replace it: \`edgegate_disconnect_byo_bucket\` ` +
|
|
74
|
+
`first (will 409 if artifacts still reference it), then re-run ` +
|
|
75
|
+
`\`edgegate_register_byo_bucket\` with the new role/bucket.`,
|
|
76
|
+
``,
|
|
77
|
+
`External-ID rotation (without replacing the grant) is available ` +
|
|
78
|
+
`via the dashboard at ` +
|
|
79
|
+
`https://edgegate.frozo.ai/workspace/${input.workspace_id}/settings#byo-storage.`,
|
|
80
|
+
].join("\n"),
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
isError: true,
|
|
87
|
+
content: [
|
|
88
|
+
{
|
|
89
|
+
type: "text",
|
|
90
|
+
text: `EdgeGate returned ${err.status}: ${err.detail}`,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
throw err;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function roleArnTail(roleArn) {
|
|
99
|
+
// arn:aws:iam::123456789012:role/edgegate-byo-storage-prod
|
|
100
|
+
// Render the trailing role name + last 4 of the account id so the user can
|
|
101
|
+
// confirm at a glance that they registered the right role.
|
|
102
|
+
const parts = roleArn.split(":");
|
|
103
|
+
if (parts.length < 6)
|
|
104
|
+
return roleArn;
|
|
105
|
+
const account = parts[4];
|
|
106
|
+
const roleName = parts.slice(5).join(":").replace(/^role\//, "");
|
|
107
|
+
const acctTail = account.length > 4 ? `…${account.slice(-4)}` : account;
|
|
108
|
+
return `${roleName} (acct ${acctTail})`;
|
|
109
|
+
}
|
|
110
|
+
function successText(grant) {
|
|
111
|
+
return {
|
|
112
|
+
content: [
|
|
113
|
+
{
|
|
114
|
+
type: "text",
|
|
115
|
+
text: [
|
|
116
|
+
`Registered BYO storage grant for this workspace.`,
|
|
117
|
+
``,
|
|
118
|
+
`- role: \`${roleArnTail(grant.role_arn)}\``,
|
|
119
|
+
`- bucket: \`${grant.bucket}\` (${grant.region})`,
|
|
120
|
+
grant.kms_key_id
|
|
121
|
+
? `- kms key: \`${grant.kms_key_id}\``
|
|
122
|
+
: `- kms key: (none — SSE-S3 or no encryption)`,
|
|
123
|
+
`- status: **${grant.status}**`,
|
|
124
|
+
`- external_id: \`${grant.external_id}\``,
|
|
125
|
+
``,
|
|
126
|
+
`**Action required if you haven't already:** add this External ID to ` +
|
|
127
|
+
`your IAM role's trust policy under \`Condition.StringEquals.sts:ExternalId\`. ` +
|
|
128
|
+
`Without it, AssumeRole will fail with BYO_ASSUME_ROLE_FAILED.`,
|
|
129
|
+
``,
|
|
130
|
+
grant.status === "active"
|
|
131
|
+
? `The readiness probe just passed. You can register your first artifact ` +
|
|
132
|
+
`with \`edgegate_register_byo_artifact\`.`
|
|
133
|
+
: grant.last_verify_error
|
|
134
|
+
? `The readiness probe FAILED: \`${grant.last_verify_error}\`. Fix the ` +
|
|
135
|
+
`IAM/bucket/KMS configuration, then re-probe with ` +
|
|
136
|
+
`\`edgegate_check_byo_bucket\`.`
|
|
137
|
+
: `Probe outcome pending — run \`edgegate_check_byo_bucket\` to verify.`,
|
|
138
|
+
].join("\n"),
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=register_byo_bucket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register_byo_bucket.js","sourceRoot":"","sources":["../../src/tools/register_byo_bucket.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -162,6 +162,19 @@ export interface APIKeyListItem {
|
|
|
162
162
|
revoked_at: string | null;
|
|
163
163
|
created_at: string;
|
|
164
164
|
}
|
|
165
|
+
export type DeviceCategory = "smartphone" | "reference" | "compute" | "iot" | "automotive" | "xr" | "other";
|
|
166
|
+
export interface DeviceEntry {
|
|
167
|
+
/** Short alias EdgeGate uses (e.g. 'sm8650'). Stable across pipeline configs. */
|
|
168
|
+
id: string;
|
|
169
|
+
/** Canonical AI Hub device name (e.g. 'Samsung Galaxy S24 (Family)'). */
|
|
170
|
+
name: string;
|
|
171
|
+
/** Form-factor / use case bucket. */
|
|
172
|
+
category: DeviceCategory;
|
|
173
|
+
}
|
|
174
|
+
export interface DeviceListResponse {
|
|
175
|
+
devices: DeviceEntry[];
|
|
176
|
+
total: number;
|
|
177
|
+
}
|
|
165
178
|
export type WorkspaceRole = "owner" | "admin" | "viewer";
|
|
166
179
|
export interface Member {
|
|
167
180
|
user_id: UUID;
|
|
@@ -269,3 +282,88 @@ export interface PromptPackCreateBody {
|
|
|
269
282
|
version: string;
|
|
270
283
|
content: PromptPackContent;
|
|
271
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Workspace's customer-owned S3 bucket grant. Returned by every grant
|
|
287
|
+
* endpoint (register / get / verify / rotate-external-id).
|
|
288
|
+
*
|
|
289
|
+
* `external_id` is shown in EVERY response — it's the value the customer
|
|
290
|
+
* has to paste into their IAM role trust policy's `sts:ExternalId`
|
|
291
|
+
* condition. We don't treat it like a secret because the trust policy
|
|
292
|
+
* already pins our AWS account as the only principal that can use it.
|
|
293
|
+
*
|
|
294
|
+
* `status` semantics: "active" = last probe passed; "failed" = last probe
|
|
295
|
+
* raised (with `last_verify_error` populated); "revoked" = grant was
|
|
296
|
+
* explicitly deleted (404 on /grants thereafter).
|
|
297
|
+
*/
|
|
298
|
+
export interface ByoGrant {
|
|
299
|
+
id: UUID;
|
|
300
|
+
workspace_id: UUID;
|
|
301
|
+
role_arn: string;
|
|
302
|
+
external_id: UUID;
|
|
303
|
+
bucket: string;
|
|
304
|
+
region: string;
|
|
305
|
+
kms_key_id: string | null;
|
|
306
|
+
status: "active" | "revoked" | "failed";
|
|
307
|
+
last_verified_at: string | null;
|
|
308
|
+
last_verify_error: string | null;
|
|
309
|
+
created_at: string;
|
|
310
|
+
updated_at: string;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Request body for POST /v1/workspaces/{ws}/artifacts/byo.
|
|
314
|
+
* Registers an existing S3 URI in the customer's grant-registered bucket
|
|
315
|
+
* as an Artifact pointer. EdgeGate does NOT upload bytes — it HeadObjects
|
|
316
|
+
* the URI to confirm existence + capture size/etag.
|
|
317
|
+
*/
|
|
318
|
+
export interface ByoArtifactRegisterRequest {
|
|
319
|
+
s3_uri: string;
|
|
320
|
+
expected_sha256?: string;
|
|
321
|
+
expected_size?: number;
|
|
322
|
+
kind?: string;
|
|
323
|
+
original_filename?: string;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* One row from the workspace's append-only `byo_storage_audit` table.
|
|
327
|
+
* `aws_request_id` is the join key for cross-referencing the customer's
|
|
328
|
+
* own CloudTrail. Nullable fields are by design for events that don't
|
|
329
|
+
* produce them (verify_probe has no run_id/artifact_id, etc.).
|
|
330
|
+
*/
|
|
331
|
+
export interface ByoAuditEntry {
|
|
332
|
+
id: number;
|
|
333
|
+
event_type: string;
|
|
334
|
+
aws_request_id: string;
|
|
335
|
+
role_arn: string;
|
|
336
|
+
bucket: string;
|
|
337
|
+
s3_key: string | null;
|
|
338
|
+
bytes_read: number | null;
|
|
339
|
+
worker_hostname: string | null;
|
|
340
|
+
outcome: string;
|
|
341
|
+
error_code: string | null;
|
|
342
|
+
artifact_id: UUID | null;
|
|
343
|
+
run_id: UUID | null;
|
|
344
|
+
ts: string;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Paginated audit-log page. `next_cursor === null` means the response
|
|
348
|
+
* contained the last page. Pass the value back as the `cursor` query
|
|
349
|
+
* param to fetch the next page.
|
|
350
|
+
*/
|
|
351
|
+
export interface ByoAuditPage {
|
|
352
|
+
entries: ByoAuditEntry[];
|
|
353
|
+
next_cursor: number | null;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Returned by POST /artifacts and POST /artifacts/byo. Mirrors the
|
|
357
|
+
* backend `ArtifactResponse` schema. `storage_url` for BYO artifacts is
|
|
358
|
+
* `byo-s3://{bucket}/{key}` rather than the managed `s3://...` form.
|
|
359
|
+
*/
|
|
360
|
+
export interface ArtifactResponse {
|
|
361
|
+
id: UUID;
|
|
362
|
+
kind: string;
|
|
363
|
+
sha256: string;
|
|
364
|
+
size_bytes: number;
|
|
365
|
+
original_filename: string | null;
|
|
366
|
+
storage_url: string;
|
|
367
|
+
created_at: string;
|
|
368
|
+
expires_at: string | null;
|
|
369
|
+
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
2
|
-
export declare const USER_AGENT = "edgegate-mcp/0.
|
|
1
|
+
export declare const VERSION = "0.9.0";
|
|
2
|
+
export declare const USER_AGENT = "edgegate-mcp/0.9.0";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
package/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edgegate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Edge-AI regression gates from Claude Code — set up CI, run benchmarks, compare runs, export reports, and fetch audit bundles from any prompt.",
|
|
5
5
|
"author": "Frozo / EdgeGate",
|
|
6
6
|
"homepage": "https://edgegate.frozo.ai",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"skills/edgegate-connect-huggingface.md",
|
|
30
30
|
"skills/edgegate-connect-qaihub.md",
|
|
31
31
|
"skills/edgegate-workspace-setup.md",
|
|
32
|
-
"skills/edgegate-members.md"
|
|
32
|
+
"skills/edgegate-members.md",
|
|
33
|
+
"skills/edgegate-byo-storage.md"
|
|
33
34
|
]
|
|
34
35
|
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: edgegate-byo-storage
|
|
3
|
+
description: Wire up BYO (bring-your-own) S3 storage for an Enterprise EdgeGate workspace — register the IAM role + bucket grant, verify the readiness probe, register the first artifact directly from the customer's bucket, and confirm the audit trail. Use when the user is on the Enterprise plan and wants model bytes to live in their own AWS account.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /edgegate-byo-storage
|
|
7
|
+
|
|
8
|
+
This is the **Enterprise BYO storage onboarding** flow. The whole point of
|
|
9
|
+
BYO is that model bytes never leave the customer's AWS account — EdgeGate's
|
|
10
|
+
workers AssumeRole into their account and read directly from their bucket.
|
|
11
|
+
|
|
12
|
+
Use this skill once per workspace, after the customer's security/IAM team
|
|
13
|
+
has provisioned the role + bucket.
|
|
14
|
+
|
|
15
|
+
## When to use
|
|
16
|
+
|
|
17
|
+
- The workspace is on the **Enterprise plan** (BYO storage 402s otherwise).
|
|
18
|
+
- The user has (or wants to provision) their own S3 bucket and IAM role.
|
|
19
|
+
- The user is migrating an existing workspace from EdgeGate-managed storage
|
|
20
|
+
to BYO, or onboarding a brand-new Enterprise workspace.
|
|
21
|
+
|
|
22
|
+
If the workspace isn't Enterprise yet, send them to
|
|
23
|
+
<https://edgegate.frozo.ai/enterprise> first — none of the
|
|
24
|
+
`edgegate_*_byo_*` tools will work until BYO is enabled on the plan.
|
|
25
|
+
|
|
26
|
+
## Pre-flight (AWS side — the user does this in their account)
|
|
27
|
+
|
|
28
|
+
You can't do this part for them, but you can hand them the exact spec:
|
|
29
|
+
|
|
30
|
+
1. **Provision the IAM role.** The fastest path is the EdgeGate
|
|
31
|
+
CloudFormation Launch Stack — link them to it from
|
|
32
|
+
<https://edgegate.frozo.ai/workspace/{workspace_id}/settings#byo-storage>.
|
|
33
|
+
(A Terraform module is also published; ask the customer which their
|
|
34
|
+
security team prefers.) The stack creates:
|
|
35
|
+
- The IAM role with `sts:AssumeRole` trusted to EdgeGate's AWS account.
|
|
36
|
+
- The S3 bucket policy granting that role `s3:GetObject` + `ListBucket`
|
|
37
|
+
scoped to the bucket only.
|
|
38
|
+
- (Optional) KMS key policy granting `kms:Decrypt` if the bucket uses
|
|
39
|
+
SSE-KMS.
|
|
40
|
+
2. **Capture** the `role_arn`, `bucket` name, `region`, and (if applicable)
|
|
41
|
+
`kms_key_id`. The trust policy's `sts:ExternalId` is left as a
|
|
42
|
+
placeholder — EdgeGate mints the real one in step 1 below and the
|
|
43
|
+
customer pastes it back.
|
|
44
|
+
|
|
45
|
+
If they want the raw IAM JSON instead of CloudFormation/Terraform, point
|
|
46
|
+
them at `docs/byo-storage-onboarding.md` in the backend repo or the
|
|
47
|
+
dashboard's "Show raw policies" link.
|
|
48
|
+
|
|
49
|
+
## Steps
|
|
50
|
+
|
|
51
|
+
1. **Register the grant.** Call
|
|
52
|
+
`edgegate_register_byo_bucket({ workspace_id, role_arn, bucket, region, kms_key_id? })`.
|
|
53
|
+
The response includes an `external_id` UUID — capture it.
|
|
54
|
+
|
|
55
|
+
2. **Paste the External ID into the IAM role trust policy.** Tell the
|
|
56
|
+
user, in plain English: "Open your IAM role in the AWS console, edit
|
|
57
|
+
the trust relationship, and replace the placeholder ExternalId with
|
|
58
|
+
`<external_id>`." Until they do this, AssumeRole will fail with
|
|
59
|
+
`BYO_ASSUME_ROLE_FAILED`.
|
|
60
|
+
|
|
61
|
+
The CloudFormation stack supports passing the External ID as a
|
|
62
|
+
parameter — point them at that if they used the stack.
|
|
63
|
+
|
|
64
|
+
3. **Verify the probe.** After the user confirms the trust policy edit
|
|
65
|
+
is saved, call `edgegate_check_byo_bucket({ workspace_id })`. Expect
|
|
66
|
+
`status: "active"`. If `status: "failed"`, the response's checklist
|
|
67
|
+
covers every typed `BYO_*` error code — read the `last_verify_error`
|
|
68
|
+
to the user, suggest the matching fix, then re-run `check`.
|
|
69
|
+
|
|
70
|
+
4. **Register the first artifact.** Pick (or ask for) an existing model
|
|
71
|
+
in the bucket. Call:
|
|
72
|
+
```
|
|
73
|
+
edgegate_register_byo_artifact({
|
|
74
|
+
workspace_id,
|
|
75
|
+
s3_uri: "s3://<bucket>/<key>.onnx",
|
|
76
|
+
expected_sha256: "<optional but recommended>",
|
|
77
|
+
})
|
|
78
|
+
```
|
|
79
|
+
Capture the returned `artifact_id`. EdgeGate did NOT download the
|
|
80
|
+
bytes — it only HeadObject'd the URI to confirm the key exists and
|
|
81
|
+
capture size + etag. The storage URL in the response will start with
|
|
82
|
+
`byo-s3://` (not `s3://`) — that's how downstream tooling routes
|
|
83
|
+
reads through the BYO service rather than EdgeGate's managed S3.
|
|
84
|
+
|
|
85
|
+
5. **Trigger the first run.** Run the artifact against an existing
|
|
86
|
+
pipeline so the customer sees the end-to-end flow work:
|
|
87
|
+
```
|
|
88
|
+
edgegate_run_gate({
|
|
89
|
+
workspace_id,
|
|
90
|
+
pipeline_id: "<existing pipeline>",
|
|
91
|
+
model_artifact_id: "<artifact_id from step 4>",
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
Poll with `edgegate_check_status` until it terminates.
|
|
95
|
+
|
|
96
|
+
6. **Show them the audit trail.** Call
|
|
97
|
+
`edgegate_get_byo_audit({ workspace_id, run_id: "<run_id from step 5>" })`.
|
|
98
|
+
The table includes one row per S3 / STS call with the
|
|
99
|
+
`aws_request_id`. Tell the user: "Cross-reference these against your
|
|
100
|
+
own CloudTrail in the same time window — every read should match."
|
|
101
|
+
This is the trust handshake the customer's security team will ask
|
|
102
|
+
for.
|
|
103
|
+
|
|
104
|
+
7. **Recap + next.** Summarize:
|
|
105
|
+
- Grant: `active`, bucket=`<name>`, region=`<region>`
|
|
106
|
+
- First artifact registered + first run executed
|
|
107
|
+
- Audit log accessible via `edgegate_get_byo_audit`
|
|
108
|
+
|
|
109
|
+
Next concrete actions:
|
|
110
|
+
- "Migrate more artifacts: `edgegate_register_byo_artifact` per s3_uri"
|
|
111
|
+
- "Schedule periodic audit pulls into your SIEM (we can stream via API)"
|
|
112
|
+
- "Rotate the External ID at any time via the dashboard"
|
|
113
|
+
|
|
114
|
+
## Failure modes
|
|
115
|
+
|
|
116
|
+
- **Register grant → 402.** Workspace is not on Enterprise. Send them to
|
|
117
|
+
<https://edgegate.frozo.ai/enterprise>.
|
|
118
|
+
- **Register grant → 409.** A grant already exists. We deliberately do
|
|
119
|
+
NOT auto-rotate — the existing grant may belong to a role the customer
|
|
120
|
+
doesn't want overwritten. Inspect with `edgegate_check_byo_bucket`,
|
|
121
|
+
then either keep it or `edgegate_disconnect_byo_bucket` and re-register.
|
|
122
|
+
External-ID-only rotation is available via the dashboard.
|
|
123
|
+
- **Check probe → status=failed with BYO_ASSUME_ROLE_FAILED.** External
|
|
124
|
+
ID drift between EdgeGate and the role's trust policy. Re-paste the
|
|
125
|
+
current external_id (visible via `edgegate_check_byo_bucket` or the
|
|
126
|
+
dashboard) into the trust policy's `sts:ExternalId` condition.
|
|
127
|
+
- **Check probe → BYO_KMS_ACCESS_DENIED.** SSE-KMS bucket but the role
|
|
128
|
+
is missing `kms:Decrypt` on the key. Add the role principal to the
|
|
129
|
+
KMS key policy.
|
|
130
|
+
- **Check probe → BYO_REGION_MISMATCH.** The bucket lives in a different
|
|
131
|
+
region than the `region` you registered. Disconnect and re-register
|
|
132
|
+
with the correct region.
|
|
133
|
+
- **Register artifact → 400 bucket mismatch.** The s3_uri points at a
|
|
134
|
+
bucket that isn't this workspace's registered one. Cross-bucket
|
|
135
|
+
pointers are forbidden — register the right bucket (or move the
|
|
136
|
+
object).
|
|
137
|
+
- **Register artifact → 400 BYO_OBJECT_NOT_FOUND.** The key is mistyped
|
|
138
|
+
or the role's bucket policy denies `ListBucket`/`GetObject` on that
|
|
139
|
+
prefix. HeadObject failures pass through with the typed code.
|
|
140
|
+
- **Disconnect → 409.** Artifacts still reference the grant. The
|
|
141
|
+
response lists the safe paths forward (drop the artifacts first, or
|
|
142
|
+
rotate the External ID via dashboard if that's what you actually
|
|
143
|
+
wanted).
|
|
144
|
+
- **Mid-run revocation** (customer revokes the role mid-run): the
|
|
145
|
+
in-flight cells complete, the rest fail with
|
|
146
|
+
`BYO_ASSUME_ROLE_FAILED`, the run terminates as `failed` (not
|
|
147
|
+
`error`) with the partial-success cells preserved in the bundle.
|
|
148
|
+
This is by design — re-grant + re-run picks up cleanly.
|