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,341 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
# AgentCore Admin — App Module (stage-level)
|
|
3
|
+
#
|
|
4
|
+
# The `agentcore-admin` Lambda is the control-plane worker that regular sandbox
|
|
5
|
+
# provisioning depends on: `createTenant` (packages/api) RequestResponse-invokes
|
|
6
|
+
# it to create per-tenant IAM roles + AgentCore Code Interpreters, and it also
|
|
7
|
+
# serves SSM permission-profile CRUD + CloudWatch audit queries. The handler
|
|
8
|
+
# lives at packages/lambda/agentcore-admin.ts and is bundled by
|
|
9
|
+
# scripts/build-lambdas.sh into dist/lambdas/agentcore-admin.zip.
|
|
10
|
+
#
|
|
11
|
+
# Historically this Lambda was built but instantiated NOWHERE — so sandbox
|
|
12
|
+
# provisioning would fail closed at runtime (AGENTCORE_ADMIN_LAMBDA_ARN unset).
|
|
13
|
+
# This module deploys it. It is intentionally a SEPARATE module with a DEDICATED
|
|
14
|
+
# least-privilege role: the handler holds a dangerous control-plane surface
|
|
15
|
+
# (iam:CreateRole, bedrock-agentcore CreateCodeInterpreter) that must never leak
|
|
16
|
+
# onto the ~90-handler shared lambda-api role.
|
|
17
|
+
#
|
|
18
|
+
# THINK-280 capability-private wiring: CAPABILITY_PRIVATE_SUBNET_IDS /
|
|
19
|
+
# CAPABILITY_PRIVATE_SECURITY_GROUP_IDS come from the capability-broker outputs
|
|
20
|
+
# (via the agentcore-code-interpreter module). Both are EMPTY when the broker is
|
|
21
|
+
# disabled (var.enable_capability_broker=false, the default) — the handler then
|
|
22
|
+
# skips capability-private provisioning entirely (capabilityPrivateProvisioning
|
|
23
|
+
# Enabled() returns false). The module therefore ships INERT for the
|
|
24
|
+
# capability-private path while still fixing the regular-provisioning gap.
|
|
25
|
+
################################################################################
|
|
26
|
+
|
|
27
|
+
terraform {
|
|
28
|
+
required_providers {
|
|
29
|
+
aws = {
|
|
30
|
+
source = "hashicorp/aws"
|
|
31
|
+
version = ">= 5.0"
|
|
32
|
+
}
|
|
33
|
+
random = {
|
|
34
|
+
source = "hashicorp/random"
|
|
35
|
+
version = ">= 3.0"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
variable "stage" {
|
|
41
|
+
description = "Deployment stage (dev, prod, etc.)."
|
|
42
|
+
type = string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
variable "region" {
|
|
46
|
+
description = "AWS region."
|
|
47
|
+
type = string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
variable "account_id" {
|
|
51
|
+
description = "AWS account ID (used to construct IAM resource ARNs)."
|
|
52
|
+
type = string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# ---- Lambda artifact sources (mirror lambda-api/remote-artifacts.tf) ----------
|
|
56
|
+
variable "lambda_zips_dir" {
|
|
57
|
+
description = "Local directory of built Lambda zips (source-checkout deploys). Mutually exclusive with lambda_artifact_bucket."
|
|
58
|
+
type = string
|
|
59
|
+
default = ""
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
variable "lambda_artifact_bucket" {
|
|
63
|
+
description = "S3 bucket holding release Lambda zips (enterprise deploys). Mutually exclusive with lambda_zips_dir."
|
|
64
|
+
type = string
|
|
65
|
+
default = ""
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
variable "lambda_artifact_prefix" {
|
|
69
|
+
description = "S3 key prefix for release Lambda zips."
|
|
70
|
+
type = string
|
|
71
|
+
default = ""
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# ---- Database (handler reads the tenants table via getDb() → DATABASE_URL) -----
|
|
75
|
+
variable "db_username" {
|
|
76
|
+
description = "Database username (used to construct DATABASE_URL)."
|
|
77
|
+
type = string
|
|
78
|
+
default = "thinkwork_admin"
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
variable "db_password" {
|
|
82
|
+
description = "Database password (used to construct DATABASE_URL)."
|
|
83
|
+
type = string
|
|
84
|
+
sensitive = true
|
|
85
|
+
default = ""
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
variable "db_cluster_endpoint" {
|
|
89
|
+
description = "Aurora cluster writer endpoint."
|
|
90
|
+
type = string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
variable "database_name" {
|
|
94
|
+
description = "Database name."
|
|
95
|
+
type = string
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
variable "graphql_db_secret_arn" {
|
|
99
|
+
description = "ARN of the writer DB credentials secret (granted GetSecretValue so db.ts's secret fallback works)."
|
|
100
|
+
type = string
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# ---- Capability-private interpreter VPC placement (THINK-280 U4) ---------------
|
|
104
|
+
# Empty when the capability broker is disabled → handler skips capability-private
|
|
105
|
+
# provisioning. Sourced from the broker outputs via the code-interpreter module.
|
|
106
|
+
variable "capability_private_subnet_ids" {
|
|
107
|
+
description = "No-NAT subnets for the capability-private VPC-mode interpreter. Empty when the broker is disabled."
|
|
108
|
+
type = list(string)
|
|
109
|
+
default = []
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
variable "capability_private_security_group_ids" {
|
|
113
|
+
description = "Egress-only SGs for the capability-private interpreter. Empty when the broker is disabled."
|
|
114
|
+
type = list(string)
|
|
115
|
+
default = []
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
################################################################################
|
|
119
|
+
# Artifact-source gating — identical semantics to lambda-api/remote-artifacts.tf.
|
|
120
|
+
# Exactly one source (local zips OR remote S3) must be set, else the Lambda is
|
|
121
|
+
# not deployed (scaffolded installs with no artifacts).
|
|
122
|
+
################################################################################
|
|
123
|
+
|
|
124
|
+
locals {
|
|
125
|
+
use_local_zips = trimspace(var.lambda_zips_dir) != ""
|
|
126
|
+
use_remote_lambda_artifacts = trimspace(var.lambda_artifact_bucket) != ""
|
|
127
|
+
lambda_artifact_prefix = trim(trimspace(var.lambda_artifact_prefix), "/")
|
|
128
|
+
artifact_source_count = (local.use_local_zips ? 1 : 0) + (local.use_remote_lambda_artifacts ? 1 : 0)
|
|
129
|
+
deploy = local.artifact_source_count == 1
|
|
130
|
+
|
|
131
|
+
function_name = "thinkwork-${var.stage}-api-agentcore-admin"
|
|
132
|
+
|
|
133
|
+
# DATABASE_URL built exactly as lambda-api's common_env does so getDb()
|
|
134
|
+
# resolves identically. sslmode=no-verify matches the shared pool (Aurora is
|
|
135
|
+
# reachable over TLS without a bundled CA in this stack).
|
|
136
|
+
database_url = "postgresql://${var.db_username}:${urlencode(var.db_password)}@${var.db_cluster_endpoint}:5432/${var.database_name}?sslmode=no-verify"
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
################################################################################
|
|
140
|
+
# Admin bearer token — random_password → Secrets Manager. The token value is
|
|
141
|
+
# ALSO injected as the Lambda's AGENTCORE_ADMIN_TOKEN env (the handler compares
|
|
142
|
+
# the Bearer header against process.env directly), and handed to graphql-http so
|
|
143
|
+
# its invoke carries the matching credential. The secret is the durable record
|
|
144
|
+
# of truth for operators / rotation.
|
|
145
|
+
################################################################################
|
|
146
|
+
|
|
147
|
+
resource "random_password" "admin_token" {
|
|
148
|
+
count = local.deploy ? 1 : 0
|
|
149
|
+
# 48 chars, alphanumeric only — safe inside an `Authorization: Bearer` header.
|
|
150
|
+
length = 48
|
|
151
|
+
special = false
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
resource "aws_secretsmanager_secret" "admin_token" {
|
|
155
|
+
count = local.deploy ? 1 : 0
|
|
156
|
+
name = "thinkwork/${var.stage}/agentcore-admin-token"
|
|
157
|
+
description = "Bearer token the agentcore-admin Lambda validates; graphql-http presents it on RequestResponse invokes."
|
|
158
|
+
|
|
159
|
+
tags = {
|
|
160
|
+
Name = "thinkwork-${var.stage}-agentcore-admin-token"
|
|
161
|
+
Stage = var.stage
|
|
162
|
+
Purpose = "agentcore-admin-bearer-token"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
resource "aws_secretsmanager_secret_version" "admin_token" {
|
|
167
|
+
count = local.deploy ? 1 : 0
|
|
168
|
+
secret_id = aws_secretsmanager_secret.admin_token[0].id
|
|
169
|
+
secret_string = random_password.admin_token[0].result
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
################################################################################
|
|
173
|
+
# IAM role — DEDICATED, least-privilege. Scoped tightly to the handler's actual
|
|
174
|
+
# AWS SDK calls (see packages/lambda/agentcore-admin.ts).
|
|
175
|
+
################################################################################
|
|
176
|
+
|
|
177
|
+
resource "aws_iam_role" "admin" {
|
|
178
|
+
count = local.deploy ? 1 : 0
|
|
179
|
+
name = "thinkwork-${var.stage}-agentcore-admin"
|
|
180
|
+
|
|
181
|
+
assume_role_policy = jsonencode({
|
|
182
|
+
Version = "2012-10-17"
|
|
183
|
+
Statement = [{
|
|
184
|
+
Effect = "Allow"
|
|
185
|
+
Principal = { Service = "lambda.amazonaws.com" }
|
|
186
|
+
Action = "sts:AssumeRole"
|
|
187
|
+
}]
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
tags = {
|
|
191
|
+
Name = "thinkwork-${var.stage}-agentcore-admin"
|
|
192
|
+
Stage = var.stage
|
|
193
|
+
Purpose = "agentcore-admin-execution-role"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
resource "aws_iam_role_policy" "admin" {
|
|
198
|
+
count = local.deploy ? 1 : 0
|
|
199
|
+
name = "agentcore-admin"
|
|
200
|
+
role = aws_iam_role.admin[0].id
|
|
201
|
+
|
|
202
|
+
policy = jsonencode({
|
|
203
|
+
Version = "2012-10-17"
|
|
204
|
+
Statement = [
|
|
205
|
+
# --- Lambda's own log group (basic execution) ---
|
|
206
|
+
{
|
|
207
|
+
Sid = "LambdaOwnLogs"
|
|
208
|
+
Effect = "Allow"
|
|
209
|
+
Action = [
|
|
210
|
+
"logs:CreateLogGroup",
|
|
211
|
+
"logs:CreateLogStream",
|
|
212
|
+
"logs:PutLogEvents",
|
|
213
|
+
]
|
|
214
|
+
Resource = "arn:aws:logs:${var.region}:${var.account_id}:log-group:/aws/lambda/${local.function_name}:*"
|
|
215
|
+
},
|
|
216
|
+
# --- CloudWatch audit query (queryAuditLogs) ---
|
|
217
|
+
{
|
|
218
|
+
Sid = "AuditLogQuery"
|
|
219
|
+
Effect = "Allow"
|
|
220
|
+
Action = ["logs:FilterLogEvents"]
|
|
221
|
+
Resource = "arn:aws:logs:${var.region}:${var.account_id}:log-group:/thinkwork/${var.stage}/agentcore/agents:*"
|
|
222
|
+
},
|
|
223
|
+
# --- SSM permission-profile CRUD (getPermissions / putPermissions) ---
|
|
224
|
+
{
|
|
225
|
+
Sid = "SsmPermissionProfiles"
|
|
226
|
+
Effect = "Allow"
|
|
227
|
+
Action = [
|
|
228
|
+
"ssm:GetParameter",
|
|
229
|
+
"ssm:PutParameter",
|
|
230
|
+
]
|
|
231
|
+
Resource = "arn:aws:ssm:${var.region}:${var.account_id}:parameter/thinkwork/${var.stage}/*"
|
|
232
|
+
},
|
|
233
|
+
# --- Per-tenant sandbox IAM roles (provision / deprovision) ---
|
|
234
|
+
# Two name prefixes: computeRoleName → sandbox-tenant-*, and the U4
|
|
235
|
+
# capability-private role → cappriv-tenant-*.
|
|
236
|
+
{
|
|
237
|
+
Sid = "SandboxRoleLifecycle"
|
|
238
|
+
Effect = "Allow"
|
|
239
|
+
Action = [
|
|
240
|
+
"iam:CreateRole",
|
|
241
|
+
"iam:DeleteRole",
|
|
242
|
+
"iam:GetRole",
|
|
243
|
+
"iam:PutRolePolicy",
|
|
244
|
+
"iam:DeleteRolePolicy",
|
|
245
|
+
"iam:TagRole",
|
|
246
|
+
]
|
|
247
|
+
Resource = [
|
|
248
|
+
"arn:aws:iam::${var.account_id}:role/thinkwork-${var.stage}-sandbox-*",
|
|
249
|
+
"arn:aws:iam::${var.account_id}:role/thinkwork-${var.stage}-cappriv-*",
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
# --- PassRole the sandbox roles to AgentCore (CreateCodeInterpreter) ---
|
|
253
|
+
{
|
|
254
|
+
Sid = "PassSandboxRolesToAgentCore"
|
|
255
|
+
Effect = "Allow"
|
|
256
|
+
Action = ["iam:PassRole"]
|
|
257
|
+
Resource = [
|
|
258
|
+
"arn:aws:iam::${var.account_id}:role/thinkwork-${var.stage}-sandbox-*",
|
|
259
|
+
"arn:aws:iam::${var.account_id}:role/thinkwork-${var.stage}-cappriv-*",
|
|
260
|
+
]
|
|
261
|
+
Condition = {
|
|
262
|
+
StringEquals = {
|
|
263
|
+
"iam:PassedToService" = "bedrock-agentcore.amazonaws.com"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
# --- AgentCore Code Interpreter control plane ---
|
|
268
|
+
# List/Create/Delete are account-scoped operations without a stable
|
|
269
|
+
# per-resource ARN at plan time; the SDK client is the control plane.
|
|
270
|
+
{
|
|
271
|
+
Sid = "CodeInterpreterControlPlane"
|
|
272
|
+
Effect = "Allow"
|
|
273
|
+
Action = [
|
|
274
|
+
"bedrock-agentcore:CreateCodeInterpreter",
|
|
275
|
+
"bedrock-agentcore:DeleteCodeInterpreter",
|
|
276
|
+
"bedrock-agentcore:ListCodeInterpreters",
|
|
277
|
+
"bedrock-agentcore:GetCodeInterpreter",
|
|
278
|
+
# CreateCodeInterpreter passes inline `tags`, which AgentCore
|
|
279
|
+
# authorizes as a separate bedrock-agentcore:TagResource action on
|
|
280
|
+
# code-interpreter-custom/* — verified empirically (first provision
|
|
281
|
+
# returned AccessDenied on TagResource). UntagResource covers teardown.
|
|
282
|
+
"bedrock-agentcore:TagResource",
|
|
283
|
+
"bedrock-agentcore:UntagResource",
|
|
284
|
+
]
|
|
285
|
+
Resource = "*"
|
|
286
|
+
},
|
|
287
|
+
# --- Secrets: DB credentials (db.ts secret fallback) + own admin token ---
|
|
288
|
+
{
|
|
289
|
+
Sid = "SecretsRead"
|
|
290
|
+
Effect = "Allow"
|
|
291
|
+
Action = ["secretsmanager:GetSecretValue"]
|
|
292
|
+
Resource = [
|
|
293
|
+
var.graphql_db_secret_arn,
|
|
294
|
+
aws_secretsmanager_secret.admin_token[0].arn,
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
]
|
|
298
|
+
})
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
################################################################################
|
|
302
|
+
# Lambda function
|
|
303
|
+
################################################################################
|
|
304
|
+
|
|
305
|
+
resource "aws_lambda_function" "admin" {
|
|
306
|
+
count = local.deploy ? 1 : 0
|
|
307
|
+
|
|
308
|
+
function_name = local.function_name
|
|
309
|
+
role = aws_iam_role.admin[0].arn
|
|
310
|
+
handler = "index.handler"
|
|
311
|
+
runtime = "nodejs20.x"
|
|
312
|
+
timeout = 60
|
|
313
|
+
memory_size = 256
|
|
314
|
+
|
|
315
|
+
filename = local.use_local_zips ? "${var.lambda_zips_dir}/agentcore-admin.zip" : null
|
|
316
|
+
source_code_hash = local.use_local_zips ? filebase64sha256("${var.lambda_zips_dir}/agentcore-admin.zip") : null
|
|
317
|
+
s3_bucket = local.use_remote_lambda_artifacts ? var.lambda_artifact_bucket : null
|
|
318
|
+
s3_key = local.use_remote_lambda_artifacts ? "${local.lambda_artifact_prefix}/agentcore-admin.zip" : null
|
|
319
|
+
|
|
320
|
+
environment {
|
|
321
|
+
variables = {
|
|
322
|
+
STAGE = var.stage
|
|
323
|
+
AWS_ACCOUNT_ID = var.account_id
|
|
324
|
+
NODE_OPTIONS = "--enable-source-maps"
|
|
325
|
+
DATABASE_URL = local.database_url
|
|
326
|
+
# Bearer token the handler validates. Secret env is the sanctioned home
|
|
327
|
+
# for secrets in this stack (never the SSM runtime-config String doc).
|
|
328
|
+
AGENTCORE_ADMIN_TOKEN = random_password.admin_token[0].result
|
|
329
|
+
# THINK-280 U4 — capability-private interpreter VPC placement. EMPTY when
|
|
330
|
+
# the broker is disabled → the handler skips capability-private entirely.
|
|
331
|
+
CAPABILITY_PRIVATE_SUBNET_IDS = join(",", var.capability_private_subnet_ids)
|
|
332
|
+
CAPABILITY_PRIVATE_SECURITY_GROUP_IDS = join(",", var.capability_private_security_group_ids)
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
tags = {
|
|
337
|
+
Name = local.function_name
|
|
338
|
+
Stage = var.stage
|
|
339
|
+
Purpose = "agentcore-admin"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
output "lambda_arn" {
|
|
2
|
+
description = "ARN of the agentcore-admin Lambda (AGENTCORE_ADMIN_LAMBDA_ARN for graphql-http). Empty when not deployed."
|
|
3
|
+
value = local.deploy ? aws_lambda_function.admin[0].arn : ""
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
output "lambda_function_name" {
|
|
7
|
+
description = "Function name of the agentcore-admin Lambda. Empty when not deployed."
|
|
8
|
+
value = local.deploy ? aws_lambda_function.admin[0].function_name : ""
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
output "admin_token" {
|
|
12
|
+
description = "Bearer token graphql-http presents on invoke (AGENTCORE_ADMIN_TOKEN). Empty when not deployed."
|
|
13
|
+
value = local.deploy ? random_password.admin_token[0].result : ""
|
|
14
|
+
sensitive = true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
output "admin_token_secret_arn" {
|
|
18
|
+
description = "ARN of the Secrets Manager secret holding the admin bearer token. Empty when not deployed."
|
|
19
|
+
value = local.deploy ? aws_secretsmanager_secret.admin_token[0].arn : ""
|
|
20
|
+
}
|
|
@@ -50,6 +50,23 @@ variable "image_retention_count" {
|
|
|
50
50
|
default = 10
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
# THINK-280 U4 — VPC placement for the capability-private interpreter. Sourced
|
|
54
|
+
# (when the capability broker is enabled) from the broker module's no-NAT
|
|
55
|
+
# interpreter subnets + dedicated egress-only SG. Empty by default: the
|
|
56
|
+
# agentcore-admin Lambda skips capability-private provisioning entirely when
|
|
57
|
+
# either list is empty, so the module stays inert with the broker disabled.
|
|
58
|
+
variable "capability_private_subnet_ids" {
|
|
59
|
+
description = "No-NAT private subnets the capability-private VPC-mode interpreter attaches to. Empty when the broker is disabled."
|
|
60
|
+
type = list(string)
|
|
61
|
+
default = []
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
variable "capability_private_security_group_ids" {
|
|
65
|
+
description = "Egress-only security groups (reach only the broker execute-api VPCE) for the capability-private interpreter. Empty when the broker is disabled."
|
|
66
|
+
type = list(string)
|
|
67
|
+
default = []
|
|
68
|
+
}
|
|
69
|
+
|
|
53
70
|
# Environment catalog. Kept as a locals block (not a variable) because v1
|
|
54
71
|
# semantics are fixed in the plan — extending requires a reviewable PR,
|
|
55
72
|
# not a tfvars tweak.
|
|
@@ -63,6 +80,14 @@ locals {
|
|
|
63
80
|
description = "S3 + DNS + AWS service endpoints only; no public egress."
|
|
64
81
|
network_mode = "SANDBOX"
|
|
65
82
|
}
|
|
83
|
+
# THINK-280 U4: VPC-mode interpreter, no NAT. Reaches ONLY the capability
|
|
84
|
+
# broker's private execute-api VPCE (+ DNS). Runtime-selected per invocation
|
|
85
|
+
# (not a template-level opt-in), and only provisioned when the broker is
|
|
86
|
+
# enabled — the agentcore-admin Lambda gates on the VPC subnet/SG env vars.
|
|
87
|
+
"capability-private" = {
|
|
88
|
+
description = "VPC-mode, no NAT; reaches only the capability broker execute-api VPCE."
|
|
89
|
+
network_mode = "VPC"
|
|
90
|
+
}
|
|
66
91
|
}
|
|
67
92
|
}
|
|
68
93
|
|
|
@@ -155,6 +180,27 @@ locals {
|
|
|
155
180
|
},
|
|
156
181
|
]
|
|
157
182
|
})
|
|
183
|
+
|
|
184
|
+
# THINK-280 U4: SEPARATE restricted inline policy for the capability-private
|
|
185
|
+
# VPC-mode interpreter role. It deliberately LACKS the tenant sandbox Secrets
|
|
186
|
+
# Manager wildcard (SandboxSecretsRead above), tenant S3, and any database /
|
|
187
|
+
# provider access — the private interpreter reaches providers only through the
|
|
188
|
+
# broker's PoP session (AE5). Logs are the only genuine boot requirement.
|
|
189
|
+
# Consumed by the agentcore-admin Lambda for the capability-private role.
|
|
190
|
+
capability_private_role_inline_policy_template = jsonencode({
|
|
191
|
+
Version = "2012-10-17"
|
|
192
|
+
Statement = [
|
|
193
|
+
{
|
|
194
|
+
Sid = "CapabilityPrivateCloudWatchLogs"
|
|
195
|
+
Effect = "Allow"
|
|
196
|
+
Action = [
|
|
197
|
+
"logs:CreateLogStream",
|
|
198
|
+
"logs:PutLogEvents",
|
|
199
|
+
]
|
|
200
|
+
Resource = "arn:aws:logs:${var.region}:${var.account_id}:log-group:/aws/bedrock-agentcore/runtimes/*"
|
|
201
|
+
},
|
|
202
|
+
]
|
|
203
|
+
})
|
|
158
204
|
}
|
|
159
205
|
|
|
160
206
|
################################################################################
|
|
@@ -191,6 +237,21 @@ output "tenant_role_inline_policy_template" {
|
|
|
191
237
|
value = local.tenant_role_inline_policy_template
|
|
192
238
|
}
|
|
193
239
|
|
|
240
|
+
output "capability_private_role_inline_policy_template" {
|
|
241
|
+
description = "THINK-280 U4: JSON inline-policy for the capability-private interpreter role. Logs-only; NO Secrets Manager / S3 / DB access."
|
|
242
|
+
value = local.capability_private_role_inline_policy_template
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
output "capability_private_subnet_ids" {
|
|
246
|
+
description = "No-NAT subnets the capability-private interpreter attaches to (CAPABILITY_PRIVATE_SUBNET_IDS). Empty when the broker is disabled."
|
|
247
|
+
value = var.capability_private_subnet_ids
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
output "capability_private_security_group_ids" {
|
|
251
|
+
description = "Egress-only SGs for the capability-private interpreter (CAPABILITY_PRIVATE_SECURITY_GROUP_IDS). Empty when the broker is disabled."
|
|
252
|
+
value = var.capability_private_security_group_ids
|
|
253
|
+
}
|
|
254
|
+
|
|
194
255
|
output "stage" {
|
|
195
256
|
description = "Echo of the stage variable (convenience for downstream modules)."
|
|
196
257
|
value = var.stage
|