thinkwork-cli 0.13.0 → 0.13.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/{api-client-JUBCQQDF.js → api-client-JYZXYQJR.js} +3 -1
- package/dist/bowser-6Z6JFAIR.js +2822 -0
- package/dist/chunk-DV3MRBR5.js +43 -0
- package/dist/chunk-DVPBI5HM.js +1728 -0
- package/dist/chunk-EI5ZX7CN.js +522 -0
- package/dist/chunk-EUJ7X6YD.js +126 -0
- package/dist/chunk-GG5WKBOX.js +436 -0
- package/dist/chunk-I64EZSU5.js +358 -0
- package/dist/chunk-ILZKG5WV.js +6151 -0
- package/dist/chunk-KMIJ5KGT.js +128 -0
- package/dist/chunk-OCPHU34C.js +996 -0
- package/dist/chunk-QOERT44A.js +3286 -0
- package/dist/chunk-XYM7PE2A.js +2264 -0
- package/dist/{chunk-STY44FQO.js → chunk-Z2F6RJFR.js} +12 -18
- package/dist/cli.js +72564 -18884
- package/dist/dist-es-CRV46D5B.js +315 -0
- package/dist/dist-es-DCY4IC3Y.js +2000 -0
- package/dist/dist-es-ENBUC3JP.js +14726 -0
- package/dist/dist-es-G54LBMRN.js +48 -0
- package/dist/dist-es-G7PTG75M.js +176 -0
- package/dist/dist-es-GKDBE7E6.js +88 -0
- package/dist/dist-es-HY3535OI.js +70 -0
- package/dist/dist-es-KL7Y5NB2.js +377 -0
- package/dist/dist-es-LDE437AM.js +170 -0
- package/dist/dist-es-P26FWFLT.js +485 -0
- package/dist/dist-es-Q57SZXZ7.js +70 -0
- package/dist/dist-es-R7FGL2IB.js +88 -0
- package/dist/dist-es-USORBXZ5.js +318 -0
- package/dist/dist-es-ZKC2QKD2.js +377 -0
- package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +2 -1
- package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +1 -0
- package/dist/drizzle/0090_brain_schema_extraction.sql +10 -0
- package/dist/drizzle/0132_drop_computer_tables.sql +3 -0
- package/dist/drizzle/0160_compliance_event_types_plugins.sql +2 -0
- package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +1 -0
- package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +1 -0
- package/dist/drizzle/0227_analyst_reader_role.sql +106 -38
- package/dist/drizzle/0230_analyst_rls.sql +192 -66
- package/dist/drizzle/0232_memory_source_thin_ledger.sql +176 -0
- package/dist/drizzle/0232_message_source_event_id.sql +9 -0
- package/dist/drizzle/0233_msteams_install_and_links.sql +151 -0
- package/dist/drizzle/0233_workflow_memory_stage_tokens.sql +20 -0
- package/dist/drizzle/0234_memory_claim_lifecycle.sql +160 -0
- package/dist/drizzle/0235_workflow_token_execution_claim.sql +34 -0
- package/dist/drizzle/0236_memory_retraction_fencing.sql +50 -0
- package/dist/drizzle/0237_memory_claims_active_value_uidx.sql +172 -0
- package/dist/drizzle/0238_memory_erase_generation_fence.sql +97 -0
- package/dist/drizzle/0239_canonical_entity_identity.sql +257 -0
- package/dist/drizzle/0240_memory_personal_scope.sql +45 -0
- package/dist/drizzle/0241_knowledge_base_document_manifest.sql +67 -0
- package/dist/drizzle/0242_search_queries.sql +28 -0
- package/dist/drizzle/0243_section_sources_thread_refs.sql +12 -0
- package/dist/drizzle/0244_system_automations_and_memory_stage_overrides.sql +45 -0
- package/dist/drizzle/0245_wiki_page_render.sql +21 -0
- package/dist/drizzle/0246_automation_workflow_ownership.sql +30 -0
- package/dist/drizzle/0247_capability_runtime.sql +402 -0
- package/dist/drizzle/0248_capability_private_interpreter.sql +13 -0
- package/dist/drizzle/0249_capability_headless_execution_evidence.sql +40 -0
- package/dist/drizzle/0250_kg_schema_extraction.sql +576 -0
- package/dist/drizzle/0251_agents_json_render_ui.sql +25 -0
- package/dist/drizzle/0251_brain_stragglers.sql +263 -0
- package/dist/drizzle/0252_drop_kg_and_straggler_compat_views.sql +100 -0
- package/dist/drizzle/0253_drop_brain_substrate.sql +93 -0
- package/dist/drizzle/0254_capability_autonomous_admission.sql +29 -0
- package/dist/drizzle/0255_capability_autonomous_approval_mode.sql +16 -0
- package/dist/drizzle/0256_agent_profile_manifest_authority.sql +18 -0
- package/dist/drizzle/0257_agents_runtime_allow_harness.sql +24 -0
- package/dist/drizzle/0257_capability_approvals.sql +53 -0
- package/dist/drizzle/0258_pending_tool_approvals.sql +84 -0
- package/dist/drizzle/0259_tenant_capability_registry_trust.sql +19 -0
- package/dist/drizzle/0260_scheduled_jobs_run_as_user.sql +20 -0
- package/dist/drizzle/0261_managed_harness_multiplayer.sql +313 -0
- package/dist/drizzle/0261_native_auth_control_plane.sql +328 -0
- package/dist/drizzle/0262_auth_subscription_tickets.sql +59 -0
- package/dist/drizzle/0262_parallel_harness_threads.sql +9 -0
- package/dist/drizzle/0263_agentcore_runtime_identifier.sql +69 -0
- package/dist/drizzle/0263_drop_workos_auth_runtime.sql +236 -0
- package/dist/drizzle/0264_auth_enrollment_attempt_limits.sql +15 -0
- package/dist/drizzle/0264_harness_tool_execution_ledger.sql +113 -0
- package/dist/drizzle/0265_eval_runs_requester_identity.sql +28 -0
- package/dist/drizzle/0265_require_fully_valid_auth_publication.sql +27 -0
- package/dist/drizzle/0266_auth_identity_recovery_grants.sql +9 -0
- package/dist/drizzle/0266_eval_profiles_runtime_type.sql +12 -0
- package/dist/drizzle/0267_ontology_candidate_rejections.sql +53 -0
- package/dist/drizzle/0268_identity_crosswalk_routing.sql +182 -0
- package/dist/drizzle/0269_ontology_system_map.sql +31 -0
- package/dist/event-streams-7JNLJEEL.js +894 -0
- package/dist/event-streams-KDF5RWR6.js +1515 -0
- package/dist/loadSso-DJVB7BXE.js +576 -0
- package/dist/loadSso-JAMNA3WY.js +583 -0
- package/dist/plugins/catalog/package.json +1 -2
- package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
- package/dist/plugins/catalog/src/__tests__/contracts.test.ts +0 -69
- package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
- package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
- package/dist/plugins/catalog/src/contracts.ts +2 -179
- package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
- package/dist/signin-UGDWTGS4.js +821 -0
- package/dist/sso-oidc-Q4VXANXY.js +837 -0
- package/dist/sts-CWLSE3GH.js +1241 -0
- package/dist/sts-DNZLNVOV.js +1245 -0
- package/dist/terraform/examples/greenfield/main.tf +247 -50
- package/dist/terraform/examples/greenfield/terraform.tfvars.example +15 -1
- package/dist/terraform/modules/app/agentcore-admin/main.tf +341 -0
- package/dist/terraform/modules/app/agentcore-admin/outputs.tf +20 -0
- package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +61 -0
- package/dist/terraform/modules/app/agentcore-gateway/main.tf +305 -0
- package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +44 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +93 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +33 -0
- package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +543 -0
- package/dist/terraform/modules/app/agentcore-gateway/variables.tf +70 -0
- package/dist/terraform/modules/app/agentcore-harness/main.tf +330 -0
- package/dist/terraform/modules/app/agentcore-harness/outputs.tf +72 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +430 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +180 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +193 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +5 -0
- package/dist/terraform/modules/app/agentcore-harness/variables.tf +96 -0
- package/dist/terraform/modules/app/agentcore-identity/main.tf +173 -0
- package/dist/terraform/modules/app/agentcore-identity/outputs.tf +51 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +122 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +25 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/delete_twenty_identity.sh +16 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +40 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_identity.sh +73 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +74 -0
- package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +61 -0
- package/dist/terraform/modules/app/agentcore-identity/variables.tf +54 -0
- package/dist/terraform/modules/app/agentcore-pi/main.tf +7 -0
- package/dist/terraform/modules/app/appsync-subscriptions/main.tf +127 -21
- package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +0 -6
- package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +5 -0
- package/dist/terraform/modules/app/capability-broker/main.tf +393 -0
- package/dist/terraform/modules/app/capability-broker/outputs.tf +54 -0
- package/dist/terraform/modules/app/capability-broker/variables.tf +98 -0
- package/dist/terraform/modules/app/deployment-control-plane/runner.py +1011 -31
- package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +655 -2
- package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +88 -0
- package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +91 -0
- package/dist/terraform/modules/app/lambda-api/capability-search-alarms.tf +60 -0
- package/dist/terraform/modules/app/lambda-api/handlers.tf +606 -37
- package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +192 -21
- package/dist/terraform/modules/app/lambda-api/main.tf +35 -0
- package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +181 -4
- package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +92 -0
- package/dist/terraform/modules/app/lambda-api/msteams-app-secrets.tf +46 -0
- package/dist/terraform/modules/app/lambda-api/outputs.tf +35 -0
- package/dist/terraform/modules/app/lambda-api/runtime-config.tf +3 -21
- package/dist/terraform/modules/app/lambda-api/variables.tf +188 -3
- package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/alarms.tf +47 -0
- package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +43 -2
- package/dist/terraform/modules/foundation/cognito/main.tf +319 -73
- package/dist/terraform/modules/foundation/cognito/outputs.tf +42 -0
- package/dist/terraform/modules/foundation/cognito/variables.tf +124 -2
- package/dist/terraform/modules/foundation/vpc/outputs.tf +5 -0
- package/dist/terraform/modules/thinkwork/main.tf +396 -26
- package/dist/terraform/modules/thinkwork/outputs.tf +188 -5
- package/dist/terraform/modules/thinkwork/variables.tf +154 -5
- package/dist/terraform/schema.graphql +69 -36
- package/dist/workspace-defaults/files/TOOLS.md +39 -0
- package/dist/workspace-defaults/files/USER.md +1 -0
- package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +18 -0
- package/dist/workspace-defaults/files/agents/coding/INSTRUCTIONS.md +11 -0
- package/dist/workspace-defaults/files/agents/research/INSTRUCTIONS.md +12 -0
- package/dist/workspace-defaults/files/agents/reviewer/INSTRUCTIONS.md +15 -0
- package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +6 -2
- package/package.json +6 -3
- package/dist/plugins/workos-auth/package.json +0 -22
- package/dist/plugins/workos-auth/src/index.ts +0 -30
- package/dist/plugins/workos-auth/src/manifest.ts +0 -40
- package/dist/plugins/workos-auth/src/provider-contract.ts +0 -39
- package/dist/plugins/workos-auth/test/manifest.test.ts +0 -94
- package/dist/plugins/workos-auth/tsconfig.json +0 -8
- /package/dist/workspace-defaults/files/{AGENTS.md → INSTRUCTIONS.md} +0 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
# THINK-316 U1 — AgentCore Gateway + Cedar proof boundary
|
|
3
|
+
#
|
|
4
|
+
# AgentCore Gateway and Policy do not yet have complete Terraform resources.
|
|
5
|
+
# The module therefore owns their lifecycle with idempotent AWS CLI scripts,
|
|
6
|
+
# matching the repo's existing AgentCore Memory pattern. All resources are
|
|
7
|
+
# proof-only and opt in; destroy removes policy -> target -> gateway -> engine.
|
|
8
|
+
################################################################################
|
|
9
|
+
|
|
10
|
+
terraform {
|
|
11
|
+
required_providers {
|
|
12
|
+
external = {
|
|
13
|
+
source = "hashicorp/external"
|
|
14
|
+
version = ">= 2.3.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
locals {
|
|
20
|
+
gateway_name = "thinkwork-${var.stage}-multiplayer-proof"
|
|
21
|
+
target_name = "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof"
|
|
22
|
+
# Policy resources accept only letters, digits, and underscores and must
|
|
23
|
+
# begin with a letter. Gateway names have a separate, hyphen-friendly API.
|
|
24
|
+
policy_engine_name = "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}MultiplayerProof"
|
|
25
|
+
policy_name = "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerIsolation"
|
|
26
|
+
# The reconciler owns the Gateway target schemas and Cedar boundary. Hash
|
|
27
|
+
# the executable itself so contract-only edits cannot leave AWS stale.
|
|
28
|
+
reconciler_hash = filesha256("${path.module}/scripts/reconcile_gateway.sh")
|
|
29
|
+
configuration_hash = nonsensitive(sha256(jsonencode({
|
|
30
|
+
discovery_url = var.discovery_url
|
|
31
|
+
audience = var.gateway_audience
|
|
32
|
+
target_url = var.target_base_url
|
|
33
|
+
provider_arn = var.oauth_credential_provider_arn
|
|
34
|
+
secret_arn = var.oauth_credential_secret_arn
|
|
35
|
+
return_url = var.oauth_return_url
|
|
36
|
+
owners = var.proof_owner_allowlist
|
|
37
|
+
capability_contract = "mcp-list-call-sandbox-builtin-platform-v7-user-questions"
|
|
38
|
+
# URL-mode OAuth elicitation requires the 2025-11-25 protocol and cannot
|
|
39
|
+
# be added to an existing Gateway, so changing this contract must replace
|
|
40
|
+
# the script-owned Gateway lifecycle.
|
|
41
|
+
protocol_versions = ["2025-03-26", "2025-11-25"]
|
|
42
|
+
reconciler = local.reconciler_hash
|
|
43
|
+
})))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
resource "aws_iam_role" "gateway_execution" {
|
|
47
|
+
count = var.enabled ? 1 : 0
|
|
48
|
+
name = "thinkwork-${var.stage}-agentcore-proof-gateway-role"
|
|
49
|
+
|
|
50
|
+
assume_role_policy = jsonencode({
|
|
51
|
+
Version = "2012-10-17"
|
|
52
|
+
Statement = [{
|
|
53
|
+
Sid = "AllowAgentCoreGateway"
|
|
54
|
+
Effect = "Allow"
|
|
55
|
+
Principal = { Service = "bedrock-agentcore.amazonaws.com" }
|
|
56
|
+
Action = "sts:AssumeRole"
|
|
57
|
+
Condition = {
|
|
58
|
+
StringEquals = { "aws:SourceAccount" = var.account_id }
|
|
59
|
+
ArnLike = { "aws:SourceArn" = "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:*" }
|
|
60
|
+
}
|
|
61
|
+
}]
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
resource "aws_iam_role_policy" "gateway_execution" {
|
|
66
|
+
count = var.enabled ? 1 : 0
|
|
67
|
+
name = "thinkwork-${var.stage}-agentcore-proof-gateway"
|
|
68
|
+
role = aws_iam_role.gateway_execution[0].id
|
|
69
|
+
|
|
70
|
+
# U1 bootstraps service-generated Gateway/Policy ids, so the dedicated
|
|
71
|
+
# proof role uses type-scoped wildcards for those two resource families.
|
|
72
|
+
# Identity and Secrets access are already scoped to exact returned ARNs;
|
|
73
|
+
# U9 replaces the bootstrap wildcards with the selected resource ids.
|
|
74
|
+
policy = jsonencode({
|
|
75
|
+
Version = "2012-10-17"
|
|
76
|
+
Statement = [
|
|
77
|
+
{
|
|
78
|
+
Sid = "PolicyEngineConfiguration"
|
|
79
|
+
Effect = "Allow"
|
|
80
|
+
Action = ["bedrock-agentcore:GetPolicyEngine"]
|
|
81
|
+
Resource = "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:policy-engine/*"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
Sid = "PolicyAuthorization"
|
|
85
|
+
Effect = "Allow"
|
|
86
|
+
Action = [
|
|
87
|
+
"bedrock-agentcore:AuthorizeAction",
|
|
88
|
+
"bedrock-agentcore:PartiallyAuthorizeActions",
|
|
89
|
+
]
|
|
90
|
+
Resource = [
|
|
91
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:policy-engine/*",
|
|
92
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:gateway/*",
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
Sid = "GatewayWorkloadToken"
|
|
97
|
+
Effect = "Allow"
|
|
98
|
+
# A CUSTOM_JWT Gateway uses the JWT-specific exchange action at
|
|
99
|
+
# runtime even though the current outbound-auth guide shows only the
|
|
100
|
+
# generic workload-token action in its example role.
|
|
101
|
+
Action = [
|
|
102
|
+
"bedrock-agentcore:GetWorkloadAccessToken",
|
|
103
|
+
"bedrock-agentcore:GetWorkloadAccessTokenForJWT",
|
|
104
|
+
]
|
|
105
|
+
Resource = [
|
|
106
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default",
|
|
107
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default/workload-identity/${local.gateway_name}-*",
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
Sid = "ExactOauthCredential"
|
|
112
|
+
Effect = "Allow"
|
|
113
|
+
Action = ["bedrock-agentcore:GetResourceOauth2Token"]
|
|
114
|
+
# Identity evaluates the request against the directory, concrete
|
|
115
|
+
# Gateway-managed workload identity, token vault, and provider. All
|
|
116
|
+
# four resource families must be present for resource-scoped access.
|
|
117
|
+
Resource = [
|
|
118
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default",
|
|
119
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default/workload-identity/${local.gateway_name}-*",
|
|
120
|
+
"arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:token-vault/default",
|
|
121
|
+
var.oauth_credential_provider_arn,
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
Sid = "ExactOauthSecret"
|
|
126
|
+
Effect = "Allow"
|
|
127
|
+
Action = ["secretsmanager:GetSecretValue"]
|
|
128
|
+
Resource = var.oauth_credential_secret_arn
|
|
129
|
+
},
|
|
130
|
+
]
|
|
131
|
+
})
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
# Keep the stable Gateway/target/policy identity separate from configuration
|
|
135
|
+
# reconciliation. A terraform_data replacement runs destroy provisioners, so
|
|
136
|
+
# coupling the configuration hash to this resource used to tear down the live
|
|
137
|
+
# Gateway before recreating it on every ordinary contract update.
|
|
138
|
+
moved {
|
|
139
|
+
from = terraform_data.gateway_lifecycle
|
|
140
|
+
to = terraform_data.gateway_identity
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
resource "terraform_data" "gateway_identity" {
|
|
144
|
+
count = var.enabled ? 1 : 0
|
|
145
|
+
|
|
146
|
+
input = {
|
|
147
|
+
region = var.region
|
|
148
|
+
gateway_name = local.gateway_name
|
|
149
|
+
target_name = local.target_name
|
|
150
|
+
policy_engine_name = local.policy_engine_name
|
|
151
|
+
policy_name = local.policy_name
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# The moved predecessor stored the full configuration hash in
|
|
155
|
+
# triggers_replace. Ignore that retired state-only attribute during the
|
|
156
|
+
# one-time split so Terraform can move the live identity without running its
|
|
157
|
+
# destroy provisioner. The dedicated configuration resource below owns all
|
|
158
|
+
# subsequent reconciliation revisions.
|
|
159
|
+
lifecycle {
|
|
160
|
+
ignore_changes = [triggers_replace]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# A brand-new identity must exist before the external data source reads it.
|
|
164
|
+
# The configuration resource performs the same idempotent reconciliation a
|
|
165
|
+
# second time on initial creation, then becomes the sole revision trigger.
|
|
166
|
+
provisioner "local-exec" {
|
|
167
|
+
command = "bash ${path.module}/scripts/reconcile_gateway.sh"
|
|
168
|
+
environment = {
|
|
169
|
+
AWS_REGION = var.region
|
|
170
|
+
GATEWAY_NAME = local.gateway_name
|
|
171
|
+
GATEWAY_ROLE_ARN = aws_iam_role.gateway_execution[0].arn
|
|
172
|
+
GATEWAY_DISCOVERY_URL = var.discovery_url
|
|
173
|
+
GATEWAY_AUDIENCE = var.gateway_audience
|
|
174
|
+
TARGET_NAME = local.target_name
|
|
175
|
+
TARGET_BASE_URL = trimsuffix(var.target_base_url, "/")
|
|
176
|
+
OAUTH_CREDENTIAL_PROVIDER_ARN = var.oauth_credential_provider_arn
|
|
177
|
+
OAUTH_RETURN_URL = var.oauth_return_url
|
|
178
|
+
POLICY_ENGINE_NAME = local.policy_engine_name
|
|
179
|
+
POLICY_NAME = local.policy_name
|
|
180
|
+
PROOF_OWNER_ALLOWLIST = var.proof_owner_allowlist
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
provisioner "local-exec" {
|
|
185
|
+
when = destroy
|
|
186
|
+
command = "bash ${path.module}/scripts/delete_gateway.sh"
|
|
187
|
+
environment = {
|
|
188
|
+
AWS_REGION = self.input.region
|
|
189
|
+
GATEWAY_NAME = self.input.gateway_name
|
|
190
|
+
TARGET_NAME = self.input.target_name
|
|
191
|
+
POLICY_ENGINE_NAME = self.input.policy_engine_name
|
|
192
|
+
POLICY_NAME = self.input.policy_name
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
depends_on = [aws_iam_role_policy.gateway_execution]
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
# Configuration revisions reconcile the stable identity in place. This
|
|
200
|
+
# terraform_data instance intentionally has no destroy provisioner: replacing
|
|
201
|
+
# it is only a signal to rerun the idempotent reconciler, never permission to
|
|
202
|
+
# delete a Gateway, target, policy, or engine.
|
|
203
|
+
resource "terraform_data" "gateway_configuration" {
|
|
204
|
+
count = var.enabled ? 1 : 0
|
|
205
|
+
|
|
206
|
+
input = local.configuration_hash
|
|
207
|
+
triggers_replace = [local.configuration_hash]
|
|
208
|
+
|
|
209
|
+
provisioner "local-exec" {
|
|
210
|
+
command = "bash ${path.module}/scripts/reconcile_gateway.sh"
|
|
211
|
+
environment = {
|
|
212
|
+
AWS_REGION = var.region
|
|
213
|
+
GATEWAY_NAME = local.gateway_name
|
|
214
|
+
GATEWAY_ROLE_ARN = aws_iam_role.gateway_execution[0].arn
|
|
215
|
+
GATEWAY_DISCOVERY_URL = var.discovery_url
|
|
216
|
+
GATEWAY_AUDIENCE = var.gateway_audience
|
|
217
|
+
TARGET_NAME = local.target_name
|
|
218
|
+
TARGET_BASE_URL = trimsuffix(var.target_base_url, "/")
|
|
219
|
+
OAUTH_CREDENTIAL_PROVIDER_ARN = var.oauth_credential_provider_arn
|
|
220
|
+
OAUTH_RETURN_URL = var.oauth_return_url
|
|
221
|
+
POLICY_ENGINE_NAME = local.policy_engine_name
|
|
222
|
+
POLICY_NAME = local.policy_name
|
|
223
|
+
PROOF_OWNER_ALLOWLIST = var.proof_owner_allowlist
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
depends_on = [terraform_data.gateway_identity]
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
data "external" "gateway_state" {
|
|
231
|
+
count = var.enabled ? 1 : 0
|
|
232
|
+
# Identity creation reconciles the Gateway before this read. Do not depend
|
|
233
|
+
# on the revision signal: doing so defers this read on every config update,
|
|
234
|
+
# makes the stable Gateway id unknown during planning, and falsely forces
|
|
235
|
+
# all CloudWatch delivery resources to replace.
|
|
236
|
+
depends_on = [terraform_data.gateway_identity]
|
|
237
|
+
program = ["bash", "${path.module}/scripts/read_gateway.sh"]
|
|
238
|
+
|
|
239
|
+
query = {
|
|
240
|
+
region = var.region
|
|
241
|
+
gateway_name = local.gateway_name
|
|
242
|
+
target_name = local.target_name
|
|
243
|
+
policy_engine_name = local.policy_engine_name
|
|
244
|
+
policy_name = local.policy_name
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
################################################################################
|
|
249
|
+
# Gateway audit evidence
|
|
250
|
+
#
|
|
251
|
+
# AgentCore does not create an application-log destination for Gateways by
|
|
252
|
+
# default. Policy decisions are enforced inside the managed Gateway, so the
|
|
253
|
+
# target Lambda cannot truthfully invent a Cedar decision id. Deliver the
|
|
254
|
+
# service-owned Gateway records instead; certification correlates those records
|
|
255
|
+
# with the target-side append-only ledger and the canonical turn.
|
|
256
|
+
################################################################################
|
|
257
|
+
|
|
258
|
+
resource "aws_cloudwatch_log_group" "gateway_application" {
|
|
259
|
+
count = var.enabled ? 1 : 0
|
|
260
|
+
name = "/aws/vendedlogs/bedrock-agentcore/gateway/APPLICATION_LOGS/${data.external.gateway_state[0].result.gateway_id}"
|
|
261
|
+
retention_in_days = var.observability_retention_days
|
|
262
|
+
|
|
263
|
+
tags = {
|
|
264
|
+
Stage = var.stage
|
|
265
|
+
Purpose = "agentcore-gateway-policy-audit"
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
resource "aws_cloudwatch_log_delivery_source" "gateway_application" {
|
|
270
|
+
count = var.enabled ? 1 : 0
|
|
271
|
+
name = "thinkwork-${var.stage}-agentcore-gateway-application"
|
|
272
|
+
log_type = "APPLICATION_LOGS"
|
|
273
|
+
resource_arn = data.external.gateway_state[0].result.gateway_arn
|
|
274
|
+
|
|
275
|
+
tags = {
|
|
276
|
+
Stage = var.stage
|
|
277
|
+
Purpose = "agentcore-gateway-policy-audit"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
resource "aws_cloudwatch_log_delivery_destination" "gateway_application" {
|
|
282
|
+
count = var.enabled ? 1 : 0
|
|
283
|
+
name = "thinkwork-${var.stage}-agentcore-gateway-cloudwatch"
|
|
284
|
+
output_format = "json"
|
|
285
|
+
|
|
286
|
+
delivery_destination_configuration {
|
|
287
|
+
destination_resource_arn = aws_cloudwatch_log_group.gateway_application[0].arn
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
tags = {
|
|
291
|
+
Stage = var.stage
|
|
292
|
+
Purpose = "agentcore-gateway-policy-audit"
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
resource "aws_cloudwatch_log_delivery" "gateway_application" {
|
|
297
|
+
count = var.enabled ? 1 : 0
|
|
298
|
+
delivery_source_name = aws_cloudwatch_log_delivery_source.gateway_application[0].name
|
|
299
|
+
delivery_destination_arn = aws_cloudwatch_log_delivery_destination.gateway_application[0].arn
|
|
300
|
+
|
|
301
|
+
tags = {
|
|
302
|
+
Stage = var.stage
|
|
303
|
+
Purpose = "agentcore-gateway-policy-audit"
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
output "gateway_id" {
|
|
2
|
+
description = "AgentCore Gateway id. Empty when disabled."
|
|
3
|
+
value = var.enabled ? data.external.gateway_state[0].result.gateway_id : ""
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "gateway_arn" {
|
|
7
|
+
description = "AgentCore Gateway ARN. Empty when disabled."
|
|
8
|
+
value = var.enabled ? data.external.gateway_state[0].result.gateway_arn : ""
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "gateway_url" {
|
|
12
|
+
description = "AgentCore Gateway MCP endpoint. Empty when disabled."
|
|
13
|
+
value = var.enabled ? data.external.gateway_state[0].result.gateway_url : ""
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
output "target_id" {
|
|
17
|
+
description = "Controlled OpenAPI target id. Empty when disabled."
|
|
18
|
+
value = var.enabled ? data.external.gateway_state[0].result.target_id : ""
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
output "target_name" {
|
|
22
|
+
description = "Controlled OpenAPI target name."
|
|
23
|
+
value = var.enabled ? local.target_name : ""
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
output "policy_engine_id" {
|
|
27
|
+
description = "Policy engine id. Empty when disabled."
|
|
28
|
+
value = var.enabled ? data.external.gateway_state[0].result.policy_engine_id : ""
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
output "policy_id" {
|
|
32
|
+
description = "Owner-isolation Cedar policy id. Empty when disabled."
|
|
33
|
+
value = var.enabled ? data.external.gateway_state[0].result.policy_id : ""
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
output "execution_role_arn" {
|
|
37
|
+
description = "Dedicated proof Gateway execution role ARN. Empty when disabled."
|
|
38
|
+
value = var.enabled ? aws_iam_role.gateway_execution[0].arn : ""
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
output "application_log_group_name" {
|
|
42
|
+
description = "CloudWatch log group receiving AgentCore Gateway application and policy records."
|
|
43
|
+
value = var.enabled ? aws_cloudwatch_log_group.gateway_application[0].name : ""
|
|
44
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
: "${AWS_REGION:?AWS_REGION is required}"
|
|
5
|
+
: "${GATEWAY_NAME:?GATEWAY_NAME is required}"
|
|
6
|
+
: "${TARGET_NAME:?TARGET_NAME is required}"
|
|
7
|
+
: "${POLICY_ENGINE_NAME:?POLICY_ENGINE_NAME is required}"
|
|
8
|
+
: "${POLICY_NAME:?POLICY_NAME is required}"
|
|
9
|
+
|
|
10
|
+
delete_error_file="$(mktemp)"
|
|
11
|
+
trap 'rm -f "$delete_error_file"' EXIT
|
|
12
|
+
|
|
13
|
+
is_not_found() {
|
|
14
|
+
grep -Eqi 'ResourceNotFoundException|not[ -]?found|does not exist' "$delete_error_file"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
delete_or_absent() {
|
|
18
|
+
: >"$delete_error_file"
|
|
19
|
+
if "$@" >/dev/null 2>"$delete_error_file"; then
|
|
20
|
+
return 0
|
|
21
|
+
fi
|
|
22
|
+
if is_not_found; then
|
|
23
|
+
return 0
|
|
24
|
+
fi
|
|
25
|
+
printf 'AgentCore delete failed: %s\n' "$(<"$delete_error_file")" >&2
|
|
26
|
+
return 1
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
wait_absent() {
|
|
30
|
+
local label="$1"
|
|
31
|
+
shift
|
|
32
|
+
for _ in $(seq 1 90); do
|
|
33
|
+
: >"$delete_error_file"
|
|
34
|
+
if "$@" >/dev/null 2>"$delete_error_file"; then
|
|
35
|
+
sleep 2
|
|
36
|
+
continue
|
|
37
|
+
fi
|
|
38
|
+
if is_not_found; then
|
|
39
|
+
return 0
|
|
40
|
+
fi
|
|
41
|
+
sleep 2
|
|
42
|
+
done
|
|
43
|
+
: >"$delete_error_file"
|
|
44
|
+
if "$@" >/dev/null 2>"$delete_error_file"; then
|
|
45
|
+
printf 'Timed out waiting for %s deletion.\n' "$label" >&2
|
|
46
|
+
return 1
|
|
47
|
+
fi
|
|
48
|
+
if is_not_found; then
|
|
49
|
+
return 0
|
|
50
|
+
fi
|
|
51
|
+
printf 'Unable to verify %s deletion: %s\n' "$label" "$(<"$delete_error_file")" >&2
|
|
52
|
+
return 1
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
gateway_json="$(aws bedrock-agentcore-control list-gateways --region "$AWS_REGION" --output json)"
|
|
56
|
+
gateway_id="$(jq -r --arg name "$GATEWAY_NAME" 'first((.items // .gateways // [])[] | select(.name == $name) | .gatewayId) // empty' <<<"$gateway_json")"
|
|
57
|
+
engine_json="$(aws bedrock-agentcore-control list-policy-engines --region "$AWS_REGION" --output json)"
|
|
58
|
+
engine_id="$(jq -r --arg name "$POLICY_ENGINE_NAME" 'first((.policyEngines // .items // [])[] | select(.name == $name) | .policyEngineId) // empty' <<<"$engine_json")"
|
|
59
|
+
|
|
60
|
+
if [[ -n "$engine_id" ]]; then
|
|
61
|
+
policy_json="$(aws bedrock-agentcore-control list-policies --region "$AWS_REGION" --policy-engine-id "$engine_id" --output json)"
|
|
62
|
+
policy_id="$(jq -r --arg name "$POLICY_NAME" 'first((.policies // .items // [])[] | select(.name == $name) | .policyId) // empty' <<<"$policy_json")"
|
|
63
|
+
if [[ -n "$policy_id" ]]; then
|
|
64
|
+
delete_or_absent aws bedrock-agentcore-control delete-policy --region "$AWS_REGION" \
|
|
65
|
+
--policy-engine-id "$engine_id" --policy-id "$policy_id"
|
|
66
|
+
wait_absent "policy $policy_id" aws bedrock-agentcore-control get-policy --region "$AWS_REGION" \
|
|
67
|
+
--policy-engine-id "$engine_id" --policy-id "$policy_id"
|
|
68
|
+
fi
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
if [[ -n "$gateway_id" ]]; then
|
|
72
|
+
target_json="$(aws bedrock-agentcore-control list-gateway-targets --region "$AWS_REGION" --gateway-identifier "$gateway_id" --output json)"
|
|
73
|
+
target_id="$(jq -r --arg name "$TARGET_NAME" 'first((.items // .targets // [])[] | select(.name == $name) | .targetId) // empty' <<<"$target_json")"
|
|
74
|
+
if [[ -n "$target_id" ]]; then
|
|
75
|
+
delete_or_absent aws bedrock-agentcore-control delete-gateway-target --region "$AWS_REGION" \
|
|
76
|
+
--gateway-identifier "$gateway_id" --target-id "$target_id"
|
|
77
|
+
wait_absent "gateway target $target_id" aws bedrock-agentcore-control get-gateway-target --region "$AWS_REGION" \
|
|
78
|
+
--gateway-identifier "$gateway_id" --target-id "$target_id"
|
|
79
|
+
fi
|
|
80
|
+
delete_or_absent aws bedrock-agentcore-control delete-gateway --region "$AWS_REGION" \
|
|
81
|
+
--gateway-identifier "$gateway_id"
|
|
82
|
+
wait_absent "gateway $gateway_id" aws bedrock-agentcore-control get-gateway --region "$AWS_REGION" \
|
|
83
|
+
--gateway-identifier "$gateway_id"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [[ -n "$engine_id" ]]; then
|
|
87
|
+
delete_or_absent aws bedrock-agentcore-control delete-policy-engine --region "$AWS_REGION" \
|
|
88
|
+
--policy-engine-id "$engine_id"
|
|
89
|
+
wait_absent "policy engine $engine_id" aws bedrock-agentcore-control get-policy-engine --region "$AWS_REGION" \
|
|
90
|
+
--policy-engine-id "$engine_id"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
printf 'AgentCore Gateway proof resources deleted or absent.\n'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
input="$(cat)"
|
|
5
|
+
region="$(jq -r '.region // empty' <<<"$input")"
|
|
6
|
+
gateway_name="$(jq -r '.gateway_name // empty' <<<"$input")"
|
|
7
|
+
target_name="$(jq -r '.target_name // empty' <<<"$input")"
|
|
8
|
+
engine_name="$(jq -r '.policy_engine_name // empty' <<<"$input")"
|
|
9
|
+
policy_name="$(jq -r '.policy_name // empty' <<<"$input")"
|
|
10
|
+
[[ -n "$region" && -n "$gateway_name" && -n "$target_name" && -n "$engine_name" && -n "$policy_name" ]]
|
|
11
|
+
|
|
12
|
+
gateway_id="$(aws bedrock-agentcore-control list-gateways --region "$region" --output json \
|
|
13
|
+
| jq -r --arg name "$gateway_name" '(.items // .gateways // [])[] | select(.name == $name) | .gatewayId' | head -n 1)"
|
|
14
|
+
engine_id="$(aws bedrock-agentcore-control list-policy-engines --region "$region" --output json \
|
|
15
|
+
| jq -r --arg name "$engine_name" '(.policyEngines // .items // [])[] | select(.name == $name) | .policyEngineId' | head -n 1)"
|
|
16
|
+
[[ -n "$gateway_id" && -n "$engine_id" ]]
|
|
17
|
+
|
|
18
|
+
gateway="$(aws bedrock-agentcore-control get-gateway --region "$region" --gateway-identifier "$gateway_id" --output json)"
|
|
19
|
+
target_id="$(aws bedrock-agentcore-control list-gateway-targets --region "$region" --gateway-identifier "$gateway_id" --output json \
|
|
20
|
+
| jq -r --arg name "$target_name" '(.items // .targets // [])[] | select(.name == $name) | .targetId' | head -n 1)"
|
|
21
|
+
policy_id="$(aws bedrock-agentcore-control list-policies --region "$region" --policy-engine-id "$engine_id" --output json \
|
|
22
|
+
| jq -r --arg name "$policy_name" '(.policies // .items // [])[] | select(.name == $name) | .policyId' | head -n 1)"
|
|
23
|
+
|
|
24
|
+
jq -n \
|
|
25
|
+
--arg gateway_id "$gateway_id" \
|
|
26
|
+
--arg gateway_arn "$(jq -r '.gatewayArn // empty' <<<"$gateway")" \
|
|
27
|
+
--arg gateway_url "$(jq -r '.gatewayUrl // .url // empty' <<<"$gateway")" \
|
|
28
|
+
--arg target_id "$target_id" \
|
|
29
|
+
--arg policy_engine_id "$engine_id" \
|
|
30
|
+
--arg policy_id "$policy_id" \
|
|
31
|
+
'if ($gateway_arn == "" or $gateway_url == "" or $target_id == "" or $policy_id == "")
|
|
32
|
+
then error("AgentCore Gateway readback omitted required identifiers")
|
|
33
|
+
else {$gateway_id, $gateway_arn, $gateway_url, $target_id, $policy_engine_id, $policy_id} end'
|