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.
Files changed (178) hide show
  1. package/dist/{api-client-JUBCQQDF.js → api-client-JYZXYQJR.js} +3 -1
  2. package/dist/bowser-6Z6JFAIR.js +2822 -0
  3. package/dist/chunk-DV3MRBR5.js +43 -0
  4. package/dist/chunk-DVPBI5HM.js +1728 -0
  5. package/dist/chunk-EI5ZX7CN.js +522 -0
  6. package/dist/chunk-EUJ7X6YD.js +126 -0
  7. package/dist/chunk-GG5WKBOX.js +436 -0
  8. package/dist/chunk-I64EZSU5.js +358 -0
  9. package/dist/chunk-ILZKG5WV.js +6151 -0
  10. package/dist/chunk-KMIJ5KGT.js +128 -0
  11. package/dist/chunk-OCPHU34C.js +996 -0
  12. package/dist/chunk-QOERT44A.js +3286 -0
  13. package/dist/chunk-XYM7PE2A.js +2264 -0
  14. package/dist/{chunk-STY44FQO.js → chunk-Z2F6RJFR.js} +12 -18
  15. package/dist/cli.js +72564 -18884
  16. package/dist/dist-es-CRV46D5B.js +315 -0
  17. package/dist/dist-es-DCY4IC3Y.js +2000 -0
  18. package/dist/dist-es-ENBUC3JP.js +14726 -0
  19. package/dist/dist-es-G54LBMRN.js +48 -0
  20. package/dist/dist-es-G7PTG75M.js +176 -0
  21. package/dist/dist-es-GKDBE7E6.js +88 -0
  22. package/dist/dist-es-HY3535OI.js +70 -0
  23. package/dist/dist-es-KL7Y5NB2.js +377 -0
  24. package/dist/dist-es-LDE437AM.js +170 -0
  25. package/dist/dist-es-P26FWFLT.js +485 -0
  26. package/dist/dist-es-Q57SZXZ7.js +70 -0
  27. package/dist/dist-es-R7FGL2IB.js +88 -0
  28. package/dist/dist-es-USORBXZ5.js +318 -0
  29. package/dist/dist-es-ZKC2QKD2.js +377 -0
  30. package/dist/drizzle/0076_scheduled_jobs_marco_backfill.sql +2 -1
  31. package/dist/drizzle/0079_seed_tenant_customize_catalog.sql +1 -0
  32. package/dist/drizzle/0090_brain_schema_extraction.sql +10 -0
  33. package/dist/drizzle/0132_drop_computer_tables.sql +3 -0
  34. package/dist/drizzle/0160_compliance_event_types_plugins.sql +2 -0
  35. package/dist/drizzle/0214_think137_drop_judge_evidence_roi.sql +1 -0
  36. package/dist/drizzle/0216_drop_agent_loop_versions_goal_worker_policy.sql +1 -0
  37. package/dist/drizzle/0227_analyst_reader_role.sql +106 -38
  38. package/dist/drizzle/0230_analyst_rls.sql +192 -66
  39. package/dist/drizzle/0232_memory_source_thin_ledger.sql +176 -0
  40. package/dist/drizzle/0232_message_source_event_id.sql +9 -0
  41. package/dist/drizzle/0233_msteams_install_and_links.sql +151 -0
  42. package/dist/drizzle/0233_workflow_memory_stage_tokens.sql +20 -0
  43. package/dist/drizzle/0234_memory_claim_lifecycle.sql +160 -0
  44. package/dist/drizzle/0235_workflow_token_execution_claim.sql +34 -0
  45. package/dist/drizzle/0236_memory_retraction_fencing.sql +50 -0
  46. package/dist/drizzle/0237_memory_claims_active_value_uidx.sql +172 -0
  47. package/dist/drizzle/0238_memory_erase_generation_fence.sql +97 -0
  48. package/dist/drizzle/0239_canonical_entity_identity.sql +257 -0
  49. package/dist/drizzle/0240_memory_personal_scope.sql +45 -0
  50. package/dist/drizzle/0241_knowledge_base_document_manifest.sql +67 -0
  51. package/dist/drizzle/0242_search_queries.sql +28 -0
  52. package/dist/drizzle/0243_section_sources_thread_refs.sql +12 -0
  53. package/dist/drizzle/0244_system_automations_and_memory_stage_overrides.sql +45 -0
  54. package/dist/drizzle/0245_wiki_page_render.sql +21 -0
  55. package/dist/drizzle/0246_automation_workflow_ownership.sql +30 -0
  56. package/dist/drizzle/0247_capability_runtime.sql +402 -0
  57. package/dist/drizzle/0248_capability_private_interpreter.sql +13 -0
  58. package/dist/drizzle/0249_capability_headless_execution_evidence.sql +40 -0
  59. package/dist/drizzle/0250_kg_schema_extraction.sql +576 -0
  60. package/dist/drizzle/0251_agents_json_render_ui.sql +25 -0
  61. package/dist/drizzle/0251_brain_stragglers.sql +263 -0
  62. package/dist/drizzle/0252_drop_kg_and_straggler_compat_views.sql +100 -0
  63. package/dist/drizzle/0253_drop_brain_substrate.sql +93 -0
  64. package/dist/drizzle/0254_capability_autonomous_admission.sql +29 -0
  65. package/dist/drizzle/0255_capability_autonomous_approval_mode.sql +16 -0
  66. package/dist/drizzle/0256_agent_profile_manifest_authority.sql +18 -0
  67. package/dist/drizzle/0257_agents_runtime_allow_harness.sql +24 -0
  68. package/dist/drizzle/0257_capability_approvals.sql +53 -0
  69. package/dist/drizzle/0258_pending_tool_approvals.sql +84 -0
  70. package/dist/drizzle/0259_tenant_capability_registry_trust.sql +19 -0
  71. package/dist/drizzle/0260_scheduled_jobs_run_as_user.sql +20 -0
  72. package/dist/drizzle/0261_managed_harness_multiplayer.sql +313 -0
  73. package/dist/drizzle/0261_native_auth_control_plane.sql +328 -0
  74. package/dist/drizzle/0262_auth_subscription_tickets.sql +59 -0
  75. package/dist/drizzle/0262_parallel_harness_threads.sql +9 -0
  76. package/dist/drizzle/0263_agentcore_runtime_identifier.sql +69 -0
  77. package/dist/drizzle/0263_drop_workos_auth_runtime.sql +236 -0
  78. package/dist/drizzle/0264_auth_enrollment_attempt_limits.sql +15 -0
  79. package/dist/drizzle/0264_harness_tool_execution_ledger.sql +113 -0
  80. package/dist/drizzle/0265_eval_runs_requester_identity.sql +28 -0
  81. package/dist/drizzle/0265_require_fully_valid_auth_publication.sql +27 -0
  82. package/dist/drizzle/0266_auth_identity_recovery_grants.sql +9 -0
  83. package/dist/drizzle/0266_eval_profiles_runtime_type.sql +12 -0
  84. package/dist/drizzle/0267_ontology_candidate_rejections.sql +53 -0
  85. package/dist/drizzle/0268_identity_crosswalk_routing.sql +182 -0
  86. package/dist/drizzle/0269_ontology_system_map.sql +31 -0
  87. package/dist/event-streams-7JNLJEEL.js +894 -0
  88. package/dist/event-streams-KDF5RWR6.js +1515 -0
  89. package/dist/loadSso-DJVB7BXE.js +576 -0
  90. package/dist/loadSso-JAMNA3WY.js +583 -0
  91. package/dist/plugins/catalog/package.json +1 -2
  92. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +0 -1
  93. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +0 -69
  94. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +0 -2
  95. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -5
  96. package/dist/plugins/catalog/src/contracts.ts +2 -179
  97. package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -6
  98. package/dist/signin-UGDWTGS4.js +821 -0
  99. package/dist/sso-oidc-Q4VXANXY.js +837 -0
  100. package/dist/sts-CWLSE3GH.js +1241 -0
  101. package/dist/sts-DNZLNVOV.js +1245 -0
  102. package/dist/terraform/examples/greenfield/main.tf +247 -50
  103. package/dist/terraform/examples/greenfield/terraform.tfvars.example +15 -1
  104. package/dist/terraform/modules/app/agentcore-admin/main.tf +341 -0
  105. package/dist/terraform/modules/app/agentcore-admin/outputs.tf +20 -0
  106. package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +61 -0
  107. package/dist/terraform/modules/app/agentcore-gateway/main.tf +305 -0
  108. package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +44 -0
  109. package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +93 -0
  110. package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +33 -0
  111. package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +543 -0
  112. package/dist/terraform/modules/app/agentcore-gateway/variables.tf +70 -0
  113. package/dist/terraform/modules/app/agentcore-harness/main.tf +330 -0
  114. package/dist/terraform/modules/app/agentcore-harness/outputs.tf +72 -0
  115. package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +5 -0
  116. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +430 -0
  117. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +180 -0
  118. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +193 -0
  119. package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +5 -0
  120. package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +5 -0
  121. package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +5 -0
  122. package/dist/terraform/modules/app/agentcore-harness/variables.tf +96 -0
  123. package/dist/terraform/modules/app/agentcore-identity/main.tf +173 -0
  124. package/dist/terraform/modules/app/agentcore-identity/outputs.tf +51 -0
  125. package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +122 -0
  126. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +25 -0
  127. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_twenty_identity.sh +16 -0
  128. package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +40 -0
  129. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_identity.sh +73 -0
  130. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +74 -0
  131. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +61 -0
  132. package/dist/terraform/modules/app/agentcore-identity/variables.tf +54 -0
  133. package/dist/terraform/modules/app/agentcore-pi/main.tf +7 -0
  134. package/dist/terraform/modules/app/appsync-subscriptions/main.tf +127 -21
  135. package/dist/terraform/modules/app/appsync-subscriptions/outputs.tf +0 -6
  136. package/dist/terraform/modules/app/appsync-subscriptions/variables.tf +5 -0
  137. package/dist/terraform/modules/app/capability-broker/main.tf +393 -0
  138. package/dist/terraform/modules/app/capability-broker/outputs.tf +54 -0
  139. package/dist/terraform/modules/app/capability-broker/variables.tf +98 -0
  140. package/dist/terraform/modules/app/deployment-control-plane/runner.py +1011 -31
  141. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +655 -2
  142. package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +88 -0
  143. package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +91 -0
  144. package/dist/terraform/modules/app/lambda-api/capability-search-alarms.tf +60 -0
  145. package/dist/terraform/modules/app/lambda-api/handlers.tf +606 -37
  146. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +192 -21
  147. package/dist/terraform/modules/app/lambda-api/main.tf +35 -0
  148. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +181 -4
  149. package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +92 -0
  150. package/dist/terraform/modules/app/lambda-api/msteams-app-secrets.tf +46 -0
  151. package/dist/terraform/modules/app/lambda-api/outputs.tf +35 -0
  152. package/dist/terraform/modules/app/lambda-api/runtime-config.tf +3 -21
  153. package/dist/terraform/modules/app/lambda-api/variables.tf +188 -3
  154. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/alarms.tf +47 -0
  155. package/dist/terraform/modules/app/workflow-interpreter-stepfunctions/main.tf +43 -2
  156. package/dist/terraform/modules/foundation/cognito/main.tf +319 -73
  157. package/dist/terraform/modules/foundation/cognito/outputs.tf +42 -0
  158. package/dist/terraform/modules/foundation/cognito/variables.tf +124 -2
  159. package/dist/terraform/modules/foundation/vpc/outputs.tf +5 -0
  160. package/dist/terraform/modules/thinkwork/main.tf +396 -26
  161. package/dist/terraform/modules/thinkwork/outputs.tf +188 -5
  162. package/dist/terraform/modules/thinkwork/variables.tf +154 -5
  163. package/dist/terraform/schema.graphql +69 -36
  164. package/dist/workspace-defaults/files/TOOLS.md +39 -0
  165. package/dist/workspace-defaults/files/USER.md +1 -0
  166. package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +18 -0
  167. package/dist/workspace-defaults/files/agents/coding/INSTRUCTIONS.md +11 -0
  168. package/dist/workspace-defaults/files/agents/research/INSTRUCTIONS.md +12 -0
  169. package/dist/workspace-defaults/files/agents/reviewer/INSTRUCTIONS.md +15 -0
  170. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +6 -2
  171. package/package.json +6 -3
  172. package/dist/plugins/workos-auth/package.json +0 -22
  173. package/dist/plugins/workos-auth/src/index.ts +0 -30
  174. package/dist/plugins/workos-auth/src/manifest.ts +0 -40
  175. package/dist/plugins/workos-auth/src/provider-contract.ts +0 -39
  176. package/dist/plugins/workos-auth/test/manifest.test.ts +0 -94
  177. package/dist/plugins/workos-auth/tsconfig.json +0 -8
  178. /package/dist/workspace-defaults/files/{AGENTS.md → INSTRUCTIONS.md} +0 -0
@@ -0,0 +1,330 @@
1
+ ################################################################################
2
+ # AgentCore Harness — App Module (THINK-316 managed multiplayer runtime)
3
+ #
4
+ # Stable execution role plus the optional managed tenant/profile Harness and
5
+ # named immutable-version endpoint.
6
+ #
7
+ # Trust-policy note: sibling agentcore roles (agentcore-pi, agentcore-runtime)
8
+ # trust the bare `bedrock-agentcore.amazonaws.com` service principal with no
9
+ # account/source-arn conditions; this role mirrors that repo pattern.
10
+ ################################################################################
11
+
12
+ terraform {
13
+ required_providers {
14
+ external = {
15
+ source = "hashicorp/external"
16
+ version = ">= 2.3.0"
17
+ }
18
+ }
19
+ }
20
+
21
+ locals {
22
+ normalized_stage = replace(var.stage, "-", "_")
23
+ normalized_tenant = replace(var.tenant_slug, "-", "_")
24
+ normalized_profile = replace(var.trust_profile, "-", "_")
25
+ harness_name = "Thinkwork_${local.normalized_stage}_${local.normalized_tenant}_${local.normalized_profile}"
26
+ # InvokeHarness accepts an endpoint name, not an immutable version. Give
27
+ # every immutable Harness version its own endpoint so the old SSM profile
28
+ # remains valid until the new endpoint snapshot is durably published.
29
+ endpoint_prefix = "ThinkworkProofV"
30
+ gateway_target_tool_names = [
31
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___owner_probe",
32
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___mixed_disclosure",
33
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___list_connector_tools",
34
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___call_connector_tool",
35
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___execute_code",
36
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___web_search",
37
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___web_extract",
38
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___query_brain",
39
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___list_workspace_skills",
40
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___load_workspace_skill",
41
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___list_message_attachments",
42
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___read_message_attachment",
43
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___ask_user_question",
44
+ "Thinkwork${replace(title(replace(var.stage, "-", " ")), " ", "")}OwnerProof___send_email",
45
+ ]
46
+ tenant_skill_prefix = var.tenant_slug != "" ? (
47
+ "tenants/${var.tenant_slug}/"
48
+ ) : "tenants/"
49
+ # These scripts are the executable Harness contract. Include their content
50
+ # in the trigger so a normal deploy reconciles prompt, tool, and lifecycle
51
+ # changes even when no symbolic contract-version string was bumped.
52
+ reconciler_hash = sha256(join("", [
53
+ filesha256("${path.module}/scripts/reconcile_harness.sh"),
54
+ filesha256("${path.module}/scripts/harness-lifecycle.mjs"),
55
+ filesha256("${path.module}/scripts/harness-tool-contract.mjs"),
56
+ ]))
57
+ configuration_hash = nonsensitive(sha256(jsonencode({
58
+ tenant_slug = var.tenant_slug
59
+ profile = var.trust_profile
60
+ discovery = var.discovery_url
61
+ audience = var.harness_audience
62
+ gateway_arn = var.gateway_arn
63
+ provider_arn = var.oauth_credential_provider_arn
64
+ return_url = var.oauth_return_url
65
+ target_tools = local.gateway_target_tool_names
66
+ model_id = var.model_id
67
+ memory = "disabled"
68
+ tool_policy = "gateway-and-cedar-authoritative"
69
+ connector_facade = "intent-ranked-direct-v1"
70
+ sandbox_facade = "bounded-internal-python-v1"
71
+ browser = "agentcore-browser-v3-canonical-name-and-participant-context"
72
+ invocation_tools = "control-plane-attested-full-override-v1"
73
+ builtin_web = "tenant-policy-secret-bound-v1"
74
+ platform_tools = "brain-email-workspace-skills-message-attachments-user-questions-v6"
75
+ artifact_facade = "caller-fulfilled-emit-document-v1"
76
+ goal_mode = "thinkwork-managed-fresh-turn-goal-complete-v1"
77
+ skill_creator = "governed-review-draft-v1"
78
+ reconciler = local.reconciler_hash
79
+ })))
80
+ }
81
+
82
+ check "managed_harness_configuration" {
83
+ assert {
84
+ condition = !var.managed_runtime_enabled || (
85
+ var.enabled &&
86
+ var.tenant_slug != "" &&
87
+ can(regex("^https://", var.discovery_url)) &&
88
+ var.harness_audience != "" &&
89
+ can(regex("^arn:aws:bedrock-agentcore:", var.gateway_arn)) &&
90
+ can(regex("^arn:aws:bedrock-agentcore:", var.oauth_credential_provider_arn)) &&
91
+ can(regex("^arn:aws:secretsmanager:", var.oauth_credential_secret_arn))
92
+ && can(regex("^https://", var.oauth_return_url))
93
+ )
94
+ error_message = "The managed AgentCore Harness requires the base role, tenant, HTTPS discovery, exact audience, Gateway, OAuth provider, and provider secret."
95
+ }
96
+ }
97
+
98
+ ################################################################################
99
+ # Harness execution role — assumed by Harness microVMs
100
+ ################################################################################
101
+
102
+ resource "aws_iam_role" "harness_execution" {
103
+ count = var.enabled ? 1 : 0
104
+
105
+ name = "thinkwork-${var.stage}-agentcore-harness-role"
106
+
107
+ assume_role_policy = jsonencode({
108
+ Version = "2012-10-17"
109
+ Statement = [{
110
+ Effect = "Allow"
111
+ Principal = { Service = "bedrock-agentcore.amazonaws.com" }
112
+ Action = "sts:AssumeRole"
113
+ }]
114
+ })
115
+
116
+ tags = {
117
+ Name = "thinkwork-${var.stage}-agentcore-harness-role"
118
+ }
119
+ }
120
+
121
+ resource "aws_iam_role_policy" "harness_execution" {
122
+ count = var.enabled ? 1 : 0
123
+
124
+ name = "agentcore-harness-permissions"
125
+ role = aws_iam_role.harness_execution[0].id
126
+
127
+ policy = jsonencode({
128
+ Version = "2012-10-17"
129
+ Statement = [
130
+ {
131
+ # Cross-region inference profiles (us.anthropic.claude-*) require
132
+ # `bedrock:InvokeModel` on the *inference-profile* ARN AND on the
133
+ # underlying foundation-model ARN in every region the profile can
134
+ # route to — same resource list the api Lambda's grouped ai policy
135
+ # uses (see ../lambda-api/iam-grouped.tf "bedrock-invoke").
136
+ Sid = "BedrockInvoke"
137
+ Effect = "Allow"
138
+ Action = ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"]
139
+ Resource = [
140
+ "arn:aws:bedrock:*::foundation-model/*",
141
+ "arn:aws:bedrock:*:${var.account_id}:inference-profile/*",
142
+ ]
143
+ },
144
+ {
145
+ # Tenant skill catalog sources + materialized workspace skill folders
146
+ # live under tenants/* in the stage workspace bucket. Read-only —
147
+ # Harness microVMs never write back to the workspace bucket.
148
+ Sid = "WorkspaceSkillSourcesRead"
149
+ Effect = "Allow"
150
+ Action = ["s3:GetObject"]
151
+ Resource = "arn:aws:s3:::${var.bucket_name}/${local.tenant_skill_prefix}*"
152
+ },
153
+ {
154
+ Sid = "WorkspaceSkillSourcesList"
155
+ Effect = "Allow"
156
+ Action = ["s3:ListBucket"]
157
+ Resource = "arn:aws:s3:::${var.bucket_name}"
158
+ Condition = {
159
+ StringLike = {
160
+ "s3:prefix" = "${local.tenant_skill_prefix}*"
161
+ }
162
+ }
163
+ },
164
+ {
165
+ # Harness containers log to the service-managed bedrock-agentcore
166
+ # log-group namespace, mirroring the agentcore-pi role's runtimes
167
+ # grant.
168
+ Sid = "CloudWatchLogs"
169
+ Effect = "Allow"
170
+ Action = [
171
+ "logs:CreateLogGroup",
172
+ "logs:CreateLogStream",
173
+ "logs:DescribeLogGroups",
174
+ "logs:DescribeLogStreams",
175
+ "logs:PutLogEvents",
176
+ ]
177
+ Resource = [
178
+ "arn:aws:logs:${var.region}:${var.account_id}:log-group:/aws/bedrock-agentcore/*",
179
+ "arn:aws:logs:${var.region}:${var.account_id}:log-group:/aws/bedrock-agentcore/*:*",
180
+ ]
181
+ },
182
+ {
183
+ Sid = "SelectedTenantGateway"
184
+ Effect = "Allow"
185
+ Action = ["bedrock-agentcore:InvokeGateway"]
186
+ Resource = var.managed_runtime_enabled ? var.gateway_arn : "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:gateway/disabled"
187
+ },
188
+ {
189
+ Sid = "ExactUserIdentityExchange"
190
+ Effect = "Allow"
191
+ Action = [
192
+ "bedrock-agentcore:GetResourceOauth2Token",
193
+ "bedrock-agentcore:GetWorkloadAccessToken",
194
+ "bedrock-agentcore:GetWorkloadAccessTokenForJWT",
195
+ ]
196
+ Resource = var.managed_runtime_enabled ? [
197
+ "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:token-vault/default",
198
+ var.oauth_credential_provider_arn,
199
+ "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default",
200
+ # AgentCore prefixes the managed runtime workload identity with
201
+ # `harness_`, then appends its generated runtime id.
202
+ "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default/workload-identity/harness_${local.harness_name}-*",
203
+ ] : ["arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:workload-identity-directory/default/workload-identity/disabled"]
204
+ },
205
+ {
206
+ Sid = "ExactOauthProviderSecret"
207
+ Effect = "Allow"
208
+ Action = ["secretsmanager:GetSecretValue"]
209
+ Resource = var.managed_runtime_enabled ? var.oauth_credential_secret_arn : "arn:aws:secretsmanager:${var.region}:${var.account_id}:secret:disabled"
210
+ },
211
+ {
212
+ # Native Harness Browser Automation. The Harness tool uses the
213
+ # service-managed Browser by default and executes under this role.
214
+ Sid = "AgentCoreBrowser"
215
+ Effect = "Allow"
216
+ Action = [
217
+ "bedrock-agentcore:StartBrowserSession",
218
+ "bedrock-agentcore:StopBrowserSession",
219
+ "bedrock-agentcore:GetBrowserSession",
220
+ "bedrock-agentcore:ListBrowserSessions",
221
+ "bedrock-agentcore:InvokeBrowser",
222
+ "bedrock-agentcore:UpdateBrowserStream",
223
+ ]
224
+ Resource = [
225
+ "arn:aws:bedrock-agentcore:${var.region}:aws:browser/aws.browser.v1",
226
+ "arn:aws:bedrock-agentcore:${var.region}:${var.account_id}:browser/*",
227
+ ]
228
+ },
229
+ {
230
+ # The service-managed Harness container resolves its public base image
231
+ # at startup under the execution role.
232
+ Sid = "PublicHarnessImage"
233
+ Effect = "Allow"
234
+ Action = [
235
+ "ecr-public:GetAuthorizationToken",
236
+ "sts:GetServiceBearerToken",
237
+ ]
238
+ Resource = "*"
239
+ },
240
+ {
241
+ Sid = "HarnessRuntimeTelemetry"
242
+ Effect = "Allow"
243
+ Action = [
244
+ "cloudwatch:PutMetricData",
245
+ "xray:PutTraceSegments",
246
+ "xray:PutTelemetryRecords",
247
+ "xray:GetSamplingRules",
248
+ "xray:GetSamplingTargets",
249
+ ]
250
+ Resource = "*"
251
+ },
252
+ ]
253
+ })
254
+ }
255
+
256
+ ################################################################################
257
+ # One stable tenant/profile Harness with immutable-version endpoint names.
258
+ ################################################################################
259
+
260
+ moved {
261
+ from = terraform_data.managed_multiplayer_harness
262
+ to = terraform_data.managed_multiplayer_harness_identity
263
+ }
264
+
265
+ # Owns deletion of the stable stage/tenant/profile identity. Configuration
266
+ # revisions are reconciled separately so an ordinary prompt/tool/model update
267
+ # creates a new immutable Harness version without replacing the Harness ARN.
268
+ resource "terraform_data" "managed_multiplayer_harness_identity" {
269
+ count = var.managed_runtime_enabled ? 1 : 0
270
+
271
+ input = {
272
+ region = var.region
273
+ harness_name = local.harness_name
274
+ endpoint_prefix = local.endpoint_prefix
275
+ }
276
+ provisioner "local-exec" {
277
+ when = destroy
278
+ command = "bash ${path.module}/scripts/delete_harness.sh"
279
+ environment = {
280
+ AWS_REGION = self.input.region
281
+ HARNESS_NAME = self.input.harness_name
282
+ ENDPOINT_PREFIX = self.input.endpoint_prefix
283
+ }
284
+ }
285
+
286
+ depends_on = [aws_iam_role_policy.harness_execution]
287
+ }
288
+
289
+ resource "terraform_data" "managed_multiplayer_harness_configuration" {
290
+ count = var.managed_runtime_enabled ? 1 : 0
291
+
292
+ input = local.configuration_hash
293
+ triggers_replace = [local.configuration_hash]
294
+
295
+ provisioner "local-exec" {
296
+ command = "bash ${path.module}/scripts/reconcile_harness.sh"
297
+ environment = {
298
+ AWS_REGION = var.region
299
+ HARNESS_NAME = local.harness_name
300
+ ENDPOINT_PREFIX = local.endpoint_prefix
301
+ EXECUTION_ROLE_ARN = aws_iam_role.harness_execution[0].arn
302
+ DISCOVERY_URL = var.discovery_url
303
+ HARNESS_AUDIENCE = var.harness_audience
304
+ GATEWAY_ARN = var.gateway_arn
305
+ GATEWAY_TARGET_TOOL_NAMES = join(",", local.gateway_target_tool_names)
306
+ OAUTH_CREDENTIAL_PROVIDER_ARN = var.oauth_credential_provider_arn
307
+ OAUTH_RETURN_URL = var.oauth_return_url
308
+ MODEL_ID = var.model_id
309
+ TENANT_SLUG = var.tenant_slug
310
+ TRUST_PROFILE = var.trust_profile
311
+ CONFIGURATION_HASH = local.configuration_hash
312
+ }
313
+ }
314
+
315
+ depends_on = [terraform_data.managed_multiplayer_harness_identity]
316
+ }
317
+
318
+ data "external" "harness_state" {
319
+ count = var.managed_runtime_enabled ? 1 : 0
320
+ depends_on = [terraform_data.managed_multiplayer_harness_configuration]
321
+ program = ["bash", "${path.module}/scripts/read_harness.sh"]
322
+
323
+ query = {
324
+ region = var.region
325
+ harness_name = local.harness_name
326
+ endpoint_prefix = local.endpoint_prefix
327
+ gateway_arn = var.gateway_arn
328
+ oauth_provider_arn = var.oauth_credential_provider_arn
329
+ }
330
+ }
@@ -0,0 +1,72 @@
1
+ output "execution_role_arn" {
2
+ description = "ARN of the Harness execution role (CreateHarness executionRoleArn). Empty string when the module is disabled."
3
+ value = var.enabled ? aws_iam_role.harness_execution[0].arn : ""
4
+ }
5
+
6
+ output "execution_role_name" {
7
+ description = "Name of the Harness execution role. Empty string when the module is disabled."
8
+ value = var.enabled ? aws_iam_role.harness_execution[0].name : ""
9
+ }
10
+
11
+ output "managed_harness_id" {
12
+ description = "Service-generated managed Harness id. Empty when the managed runtime is disabled."
13
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.harness_id : ""
14
+ }
15
+
16
+ output "managed_harness_arn" {
17
+ description = "One tenant/profile Harness ARN. Empty when disabled."
18
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.harness_arn : ""
19
+ }
20
+
21
+ output "managed_endpoint_name" {
22
+ description = "Immutable-version Harness endpoint qualifier. Empty when disabled."
23
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.endpoint_name : ""
24
+ }
25
+
26
+ output "managed_endpoint_arn" {
27
+ description = "Named Harness endpoint ARN. Empty when disabled."
28
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.endpoint_arn : ""
29
+ }
30
+
31
+ output "managed_target_version" {
32
+ description = "Immutable Harness version attested by the named endpoint. Empty when disabled."
33
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.target_version : ""
34
+ }
35
+
36
+ output "managed_live_version" {
37
+ description = "Live version returned by the endpoint readback. Must equal managed_target_version for readiness."
38
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.live_version : ""
39
+ }
40
+
41
+ output "managed_model_id" {
42
+ description = "Actual Bedrock model configured on the immutable Harness version."
43
+ value = var.managed_runtime_enabled ? var.model_id : ""
44
+ }
45
+
46
+ output "managed_status" {
47
+ description = "Derived safe readiness state: disabled, provisioning, ready, drifted, or misconfigured."
48
+ value = !var.managed_runtime_enabled ? "disabled" : (
49
+ data.external.harness_state[0].result.harness_status != "READY" || data.external.harness_state[0].result.endpoint_status != "READY" ? "provisioning" : (
50
+ data.external.harness_state[0].result.target_version != data.external.harness_state[0].result.live_version ? "drifted" : "ready"
51
+ )
52
+ )
53
+ }
54
+
55
+ output "managed_configuration_fingerprint" {
56
+ description = "Non-secret fingerprint binding desired configuration to the immutable endpoint tool snapshot."
57
+ value = var.managed_runtime_enabled ? sha256(jsonencode({
58
+ desired_configuration = local.configuration_hash
59
+ harness_version = data.external.harness_state[0].result.harness_version
60
+ invocation_tools = jsondecode(data.external.harness_state[0].result.invocation_tools_json)
61
+ })) : ""
62
+ }
63
+
64
+ output "managed_invocation_tools_json" {
65
+ description = "Exact non-secret live Harness tool configuration serialized for the managed data-plane profile."
66
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.invocation_tools_json : "[]"
67
+ }
68
+
69
+ output "managed_invocation_tools_fingerprint" {
70
+ description = "JavaScript-canonical SHA-256 digest of the immutable endpoint invocation-tool snapshot."
71
+ value = var.managed_runtime_enabled ? data.external.harness_state[0].result.invocation_tools_fingerprint : ""
72
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ exec node "$script_dir/harness-lifecycle.mjs" delete