thinkwork-cli 0.13.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +3 -14
  2. package/dist/{api-client-JYZXYQJR.js → api-client-4P4JZOBX.js} +1 -1
  3. package/dist/{chunk-Z2F6RJFR.js → chunk-4OMDWYZQ.js} +4 -5
  4. package/dist/{chunk-ILZKG5WV.js → chunk-AD2NIWB5.js} +434 -69
  5. package/dist/chunk-MWQ7RO76.js +137 -0
  6. package/dist/{chunk-DVPBI5HM.js → chunk-OLUQ4U2Z.js} +26 -26
  7. package/dist/{chunk-QOERT44A.js → chunk-YQCYD6NE.js} +57 -44
  8. package/dist/cli.js +4400 -16431
  9. package/dist/commands/enterprise/templates/deploy-repo/scripts/apply-release.mjs +0 -1
  10. package/dist/commands/enterprise/templates/deploy-repo/scripts/smoke.mjs +0 -1
  11. package/dist/commands/enterprise/templates/deploy-repo/terraform/main.tf +0 -14
  12. package/dist/{dist-es-CRV46D5B.js → dist-es-2OTNTL4N.js} +4 -4
  13. package/dist/{dist-es-ENBUC3JP.js → dist-es-2XVAH4BQ.js} +2 -2
  14. package/dist/{dist-es-DCY4IC3Y.js → dist-es-3DPDUJAH.js} +2 -2
  15. package/dist/{dist-es-G7PTG75M.js → dist-es-BNZTBBVC.js} +1 -1
  16. package/dist/{dist-es-GKDBE7E6.js → dist-es-CD2RBDAC.js} +1 -1
  17. package/dist/{dist-es-R7FGL2IB.js → dist-es-I4FW57PS.js} +1 -1
  18. package/dist/{dist-es-USORBXZ5.js → dist-es-KVFWJNDY.js} +4 -4
  19. package/dist/{dist-es-HY3535OI.js → dist-es-PS73DWNL.js} +2 -2
  20. package/dist/{dist-es-LDE437AM.js → dist-es-S3NZQFGT.js} +1 -1
  21. package/dist/{dist-es-G54LBMRN.js → dist-es-SGCA4P32.js} +1 -1
  22. package/dist/{dist-es-Q57SZXZ7.js → dist-es-WBM6J4RA.js} +2 -2
  23. package/dist/{dist-es-P26FWFLT.js → dist-es-ZGVADYIF.js} +8 -8
  24. package/dist/drizzle/0227_analyst_reader_role.sql +17 -26
  25. package/dist/drizzle/0230_analyst_rls.sql +28 -45
  26. package/dist/drizzle/0261_native_auth_control_plane.sql +7 -3
  27. package/dist/drizzle/0270_tool_execution_ledger.sql +115 -0
  28. package/dist/drizzle/0271_ontology_twin_declarations.sql +47 -0
  29. package/dist/drizzle/0272_identity_graph_projection_cursor.sql +23 -0
  30. package/dist/drizzle/0273_twin_materialization_suggestions.sql +29 -0
  31. package/dist/drizzle/0274_tenant_mcp_twin_keys.sql +59 -0
  32. package/dist/drizzle/0275_identity_bulk_rebuild_fence.sql +30 -0
  33. package/dist/drizzle/0276_tool_execution_ledger_allow_cascade_delete.sql +18 -0
  34. package/dist/drizzle/0277_knowledge_base_sources.sql +107 -0
  35. package/dist/drizzle/0278_kb_page_transcription.sql +55 -0
  36. package/dist/drizzle/0279_mcp_servers_off_plugin_provenance.sql +93 -0
  37. package/dist/drizzle/0280_work_item_external_refs_drop_plane_provider.sql +46 -0
  38. package/dist/drizzle/0281_tenant_mcp_twin_keys_expiry_suffix.sql +9 -0
  39. package/dist/drizzle/0282_tenant_mcp_twin_keys_grants.sql +24 -0
  40. package/dist/drizzle/0283_agents_agentcore_runtime_dispatch.sql +13 -0
  41. package/dist/drizzle/0284_user_brain_claims.sql +69 -0
  42. package/dist/drizzle/0285_tenant_mcp_twin_keys_trusted_subsystem.sql +30 -0
  43. package/dist/drizzle/0286_brain_analytics_key.sql +26 -0
  44. package/dist/drizzle/0287_brain_subject.sql +25 -0
  45. package/dist/drizzle/0288_multi_lane_identities.sql +25 -0
  46. package/dist/{loadSso-DJVB7BXE.js → loadSso-ETCXTR4I.js} +2 -2
  47. package/dist/{loadSso-JAMNA3WY.js → loadSso-UBD7KUHE.js} +2 -2
  48. package/dist/plugins/README.md +2 -2
  49. package/dist/plugins/catalog/package.json +0 -3
  50. package/dist/plugins/catalog/src/__tests__/build-catalog.test.ts +6 -3
  51. package/dist/plugins/catalog/src/__tests__/catalog.test.ts +21 -21
  52. package/dist/plugins/catalog/src/__tests__/contracts.test.ts +102 -25
  53. package/dist/plugins/catalog/src/__tests__/plugin-package.test.ts +7 -6
  54. package/dist/plugins/catalog/src/__tests__/plugin-registry.test.ts +0 -15
  55. package/dist/plugins/catalog/src/contracts.ts +15 -0
  56. package/dist/plugins/catalog/src/registry/generated-first-party.ts +0 -18
  57. package/dist/plugins/n8n/test/integrated-app-contract.test.ts +1 -1
  58. package/dist/plugins/twenty/package.json +2 -1
  59. package/dist/plugins/twenty/scripts/LAMBDA_DEPLOY.md +114 -0
  60. package/dist/plugins/twenty/scripts/build-lambda.sh +29 -0
  61. package/dist/plugins/twenty/scripts/configure-product-views.ts +195 -0
  62. package/dist/plugins/twenty/scripts/lambda-handler.ts +49 -0
  63. package/dist/plugins/twenty/scripts/lib/__tests__/load-attachments.test.ts +38 -0
  64. package/dist/plugins/twenty/scripts/lib/__tests__/load-records.test.ts +145 -2
  65. package/dist/plugins/twenty/scripts/lib/__tests__/mappers.test.ts +397 -151
  66. package/dist/plugins/twenty/scripts/lib/__tests__/members-ensure.test.ts +28 -129
  67. package/dist/plugins/twenty/scripts/lib/__tests__/provision-members-db.test.ts +10 -0
  68. package/dist/plugins/twenty/scripts/lib/__tests__/schema-ensure.test.ts +13 -8
  69. package/dist/plugins/twenty/scripts/lib/lastmile-reader.ts +222 -2
  70. package/dist/plugins/twenty/scripts/lib/load-attachments.ts +29 -0
  71. package/dist/plugins/twenty/scripts/lib/load-records.ts +160 -43
  72. package/dist/plugins/twenty/scripts/lib/mappers.ts +368 -152
  73. package/dist/plugins/twenty/scripts/lib/members-ensure.ts +43 -268
  74. package/dist/plugins/twenty/scripts/lib/provision-members-db.ts +57 -0
  75. package/dist/plugins/twenty/scripts/lib/schema-ensure.ts +136 -31
  76. package/dist/plugins/twenty/scripts/migrate-lastmile.ts +254 -152
  77. package/dist/plugins/twenty/scripts/provision-twenty-members.ts +44 -1
  78. package/dist/plugins/twenty/scripts/purge-lastmile-import.ts +178 -0
  79. package/dist/plugins/twenty/scripts/restructure-products.ts +312 -0
  80. package/dist/plugins/twenty/scripts/retag-stage-values.ts +362 -0
  81. package/dist/plugins/twenty/test/manifest.test.ts +2 -4
  82. package/dist/scripts/post-deploy.sh +79 -1
  83. package/dist/{signin-UGDWTGS4.js → signin-5QZNRSOO.js} +2 -2
  84. package/dist/{sso-oidc-Q4VXANXY.js → sso-oidc-XK673P54.js} +2 -2
  85. package/dist/{sts-CWLSE3GH.js → sts-OXI2UALF.js} +6 -134
  86. package/dist/{sts-DNZLNVOV.js → sts-SQW4NBK3.js} +6 -134
  87. package/dist/terraform/examples/greenfield/main.tf +233 -175
  88. package/dist/terraform/examples/greenfield/terraform.tfvars.example +12 -8
  89. package/dist/terraform/modules/app/agentcore-admin/main.tf +47 -0
  90. package/dist/terraform/modules/app/agentcore-code-interpreter/README.md +39 -47
  91. package/dist/terraform/modules/app/agentcore-code-interpreter/main.tf +13 -66
  92. package/dist/terraform/modules/app/agentcore-identity/main.tf +106 -26
  93. package/dist/terraform/modules/app/agentcore-identity/outputs.tf +6 -6
  94. package/dist/terraform/modules/app/agentcore-identity/scripts/bootstrap_twenty_oauth_client.sh +216 -99
  95. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_identity.sh +6 -9
  96. package/dist/terraform/modules/app/agentcore-identity/scripts/delete_workload_identity.sh +19 -0
  97. package/dist/terraform/modules/app/agentcore-identity/scripts/ensure_workload_identity.sh +29 -0
  98. package/dist/terraform/modules/app/agentcore-identity/scripts/read_identity.sh +22 -7
  99. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_identity.sh +17 -46
  100. package/dist/terraform/modules/app/agentcore-identity/scripts/reconcile_twenty_provider.mjs +65 -3
  101. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/after.tf +15 -0
  102. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/before.tf +7 -0
  103. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-after.tf +8 -0
  104. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/identity-before.tf +9 -0
  105. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-after.tf +3 -0
  106. package/dist/terraform/modules/app/agentcore-identity/tests/tainted-marker/thinkwork-before.tf +3 -0
  107. package/dist/terraform/modules/app/agentcore-identity/variables.tf +6 -0
  108. package/dist/terraform/modules/app/agentcore-memory/README.md +46 -9
  109. package/dist/terraform/modules/app/agentcore-memory/main.tf +27 -10
  110. package/dist/terraform/modules/app/agentcore-memory/scripts/create_or_find_memory.sh +156 -24
  111. package/dist/terraform/modules/app/agentcore-pi/README.md +1 -3
  112. package/dist/terraform/modules/app/agentcore-pi/main.tf +42 -52
  113. package/dist/terraform/modules/app/agentcore-pi/outputs.tf +3 -3
  114. package/dist/terraform/modules/app/agentcore-pi/scripts/reconcile_pi_runtime.mjs +175 -0
  115. package/dist/terraform/modules/app/agentcore-pi/variables.tf +35 -28
  116. package/dist/terraform/modules/app/agentcore-platform/main.tf +68 -0
  117. package/dist/terraform/modules/app/agentcore-runtime/main.tf +4 -20
  118. package/dist/terraform/modules/app/capability-broker/main.tf +2 -2
  119. package/dist/terraform/modules/app/capability-broker/variables.tf +11 -0
  120. package/dist/terraform/modules/app/deployment-control-plane/README.md +264 -0
  121. package/dist/terraform/modules/app/deployment-control-plane/buildspec.yml +4 -1
  122. package/dist/terraform/modules/app/deployment-control-plane/main.tf +94 -0
  123. package/dist/terraform/modules/app/deployment-control-plane/outputs.tf +5 -0
  124. package/dist/terraform/modules/app/deployment-control-plane/runner.py +2641 -124
  125. package/dist/terraform/modules/app/deployment-control-plane/test_runner_bundle.py +2034 -154
  126. package/dist/terraform/modules/app/deployment-control-plane/variables.tf +33 -0
  127. package/dist/terraform/modules/app/lambda-api/auth-state.tf +72 -0
  128. package/dist/terraform/modules/app/lambda-api/chat-latency-observability.tf +466 -0
  129. package/dist/terraform/modules/app/lambda-api/dispatch-dlq.tf +55 -0
  130. package/dist/terraform/modules/app/lambda-api/handlers.tf +411 -723
  131. package/dist/terraform/modules/app/lambda-api/iam-grouped.tf +262 -198
  132. package/dist/terraform/modules/app/lambda-api/main.tf +51 -13
  133. package/dist/terraform/modules/app/lambda-api/mcp-oauth.tf +4 -181
  134. package/dist/terraform/modules/app/lambda-api/memory-alarms.tf +3 -28
  135. package/dist/terraform/modules/app/lambda-api/oauth-secrets.tf +1 -2
  136. package/dist/terraform/modules/app/lambda-api/outputs.tf +17 -45
  137. package/dist/terraform/modules/app/lambda-api/turn-assertion.tf +45 -0
  138. package/dist/terraform/modules/app/lambda-api/variables.tf +219 -126
  139. package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/README.md +1 -1
  140. package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/main.tf +18 -18
  141. package/dist/terraform/modules/app/sandbox-log-scrubber/README.md +11 -10
  142. package/dist/terraform/modules/app/sandbox-log-scrubber/main.tf +5 -5
  143. package/dist/terraform/modules/app/static-site/main.tf +1 -1
  144. package/dist/terraform/modules/app/www-dns/main.tf +9 -27
  145. package/dist/terraform/modules/app/www-dns/variables.tf +4 -10
  146. package/dist/terraform/modules/data/aurora-postgres/README.md +34 -0
  147. package/dist/terraform/modules/data/aurora-postgres/alarms.tf +82 -0
  148. package/dist/terraform/modules/data/aurora-postgres/main.tf +27 -57
  149. package/dist/terraform/modules/data/aurora-postgres/outputs.tf +0 -9
  150. package/dist/terraform/modules/data/aurora-postgres/variables.tf +41 -0
  151. package/dist/terraform/modules/data/s3-buckets/main.tf +5 -6
  152. package/dist/terraform/modules/foundation/cognito/main.tf +81 -8
  153. package/dist/terraform/modules/foundation/cognito/outputs.tf +5 -0
  154. package/dist/terraform/modules/foundation/cognito/variables.tf +24 -12
  155. package/dist/terraform/modules/thinkwork/README.md +5 -1
  156. package/dist/terraform/modules/thinkwork/main.tf +376 -374
  157. package/dist/terraform/modules/thinkwork/outputs.tf +12 -158
  158. package/dist/terraform/modules/thinkwork/variables.tf +246 -89
  159. package/dist/workspace-defaults/files/INSTRUCTIONS.md +9 -11
  160. package/dist/workspace-defaults/files/MEMORY_GUIDE.md +38 -35
  161. package/dist/workspace-defaults/files/ROUTER.md +1 -1
  162. package/dist/workspace-defaults/files/TOOLS.md +9 -39
  163. package/dist/workspace-defaults/files/agents/analyst/INSTRUCTIONS.md +6 -3
  164. package/dist/workspace-defaults/files/catalog-skills/brain-brief-builder/SKILL.md +165 -0
  165. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/SKILL.md +75 -0
  166. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/mcp-tooling.md +40 -0
  167. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/validation-and-handoff.md +40 -0
  168. package/dist/workspace-defaults/files/catalog-skills/n8n-workflow-operator/references/workflow-authoring.md +46 -0
  169. package/dist/workspace-defaults/files/skills/artifact-builder/references/crm-dashboard.md +1 -1
  170. package/dist/workspace-defaults/files/skills/document-composer/SKILL.md +22 -3
  171. package/package.json +1 -1
  172. package/dist/drizzle/0261_managed_harness_multiplayer.sql +0 -313
  173. package/dist/drizzle/0262_parallel_harness_threads.sql +0 -9
  174. package/dist/drizzle/0264_harness_tool_execution_ledger.sql +0 -113
  175. package/dist/plugins/company-data/README.md +0 -49
  176. package/dist/plugins/company-data/package.json +0 -21
  177. package/dist/plugins/company-data/src/index.ts +0 -30
  178. package/dist/plugins/company-data/src/manifest.ts +0 -26
  179. package/dist/plugins/company-data/test/manifest.test.ts +0 -116
  180. package/dist/plugins/company-data/tsconfig.json +0 -8
  181. package/dist/plugins/company-etl/README.md +0 -46
  182. package/dist/plugins/company-etl/package.json +0 -21
  183. package/dist/plugins/company-etl/src/index.ts +0 -29
  184. package/dist/plugins/company-etl/src/manifest.ts +0 -26
  185. package/dist/plugins/company-etl/test/manifest.test.ts +0 -108
  186. package/dist/plugins/company-etl/tsconfig.json +0 -8
  187. package/dist/plugins/lastmile/README.md +0 -50
  188. package/dist/plugins/lastmile/package.json +0 -23
  189. package/dist/plugins/lastmile/smoke/lastmile-plugin-smoke.mjs +0 -661
  190. package/dist/plugins/lastmile/src/api/tasks-adapter.ts +0 -572
  191. package/dist/plugins/lastmile/src/discovery.fixture.ts +0 -64
  192. package/dist/plugins/lastmile/src/index.ts +0 -46
  193. package/dist/plugins/lastmile/src/manifest.ts +0 -139
  194. package/dist/plugins/lastmile/test/api/tasks-adapter.test.ts +0 -266
  195. package/dist/plugins/lastmile/test/discovery.test.ts +0 -88
  196. package/dist/plugins/lastmile/tsconfig.json +0 -8
  197. package/dist/plugins/n8n/smoke/n8n-managed-app-smoke.mjs +0 -409
  198. package/dist/plugins/twenty/smoke/twenty-managed-app-smoke.mjs +0 -359
  199. package/dist/terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base +0 -61
  200. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/sitecustomize.py +0 -227
  201. package/dist/terraform/modules/app/agentcore-code-interpreter/sandbox/test_sitecustomize.py +0 -277
  202. package/dist/terraform/modules/app/agentcore-code-interpreter/scripts/build_and_push_sandbox_base.sh +0 -70
  203. package/dist/terraform/modules/app/agentcore-gateway/main.tf +0 -305
  204. package/dist/terraform/modules/app/agentcore-gateway/outputs.tf +0 -44
  205. package/dist/terraform/modules/app/agentcore-gateway/scripts/delete_gateway.sh +0 -93
  206. package/dist/terraform/modules/app/agentcore-gateway/scripts/read_gateway.sh +0 -33
  207. package/dist/terraform/modules/app/agentcore-gateway/scripts/reconcile_gateway.sh +0 -543
  208. package/dist/terraform/modules/app/agentcore-gateway/variables.tf +0 -70
  209. package/dist/terraform/modules/app/agentcore-harness/main.tf +0 -330
  210. package/dist/terraform/modules/app/agentcore-harness/outputs.tf +0 -72
  211. package/dist/terraform/modules/app/agentcore-harness/scripts/delete_harness.sh +0 -5
  212. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-lifecycle.mjs +0 -430
  213. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-readback.mjs +0 -180
  214. package/dist/terraform/modules/app/agentcore-harness/scripts/harness-tool-contract.mjs +0 -193
  215. package/dist/terraform/modules/app/agentcore-harness/scripts/prune_harness.sh +0 -5
  216. package/dist/terraform/modules/app/agentcore-harness/scripts/read_harness.sh +0 -5
  217. package/dist/terraform/modules/app/agentcore-harness/scripts/reconcile_harness.sh +0 -5
  218. package/dist/terraform/modules/app/agentcore-harness/variables.tf +0 -96
  219. package/dist/terraform/modules/app/hindsight-memory/README.md +0 -89
  220. package/dist/terraform/modules/app/hindsight-memory/main.tf +0 -411
  221. package/dist/terraform/modules/app/lambda-api/agentcore-harness-alarms.tf +0 -88
  222. package/dist/terraform/modules/app/lambda-api/agentcore-identity-alarms.tf +0 -91
  223. package/dist/terraform/modules/data/bedrock-knowledge-base/main.tf +0 -102
  224. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/outputs.tf +0 -0
  225. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/sync-database.py +0 -0
  226. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/scripts/test_sync_database.py +0 -0
  227. /package/dist/{plugins/n8n/terraform → terraform/modules/app}/n8n/variables.tf +0 -0
  228. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/README.md +0 -0
  229. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/main.tf +0 -0
  230. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/outputs.tf +0 -0
  231. /package/dist/{plugins/twenty/terraform → terraform/modules/app}/twenty/variables.tf +0 -0
@@ -1,277 +0,0 @@
1
- """Unit tests for the AgentCore sandbox base-image stdio token redactor.
2
-
3
- Tests hit ``_RedactingStream`` directly with a test-owned stream instead of
4
- mutating ``sys.stdout`` — that side-steps pytest's capture machinery, which
5
- owns sys.stdout at test time and would otherwise see writes before the
6
- wrapper does. Correctness of the sys.stdout replacement path is proven by
7
- a separate end-to-end test that runs the module as a subprocess with its
8
- auto-install path active.
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- import base64
14
- import binascii
15
- import importlib.util
16
- import io
17
- import os
18
- import subprocess
19
- import sys
20
- import urllib.parse
21
-
22
- import pytest
23
-
24
- os.environ["THINKWORK_SANDBOX_SCRUBBER"] = "off"
25
-
26
- _HERE = os.path.dirname(os.path.abspath(__file__))
27
- _SPEC = importlib.util.spec_from_file_location(
28
- "sandbox_base_sitecustomize",
29
- os.path.join(_HERE, "sitecustomize.py"),
30
- )
31
- assert _SPEC is not None and _SPEC.loader is not None
32
- sc = importlib.util.module_from_spec(_SPEC)
33
- _SPEC.loader.exec_module(sc)
34
-
35
-
36
- class _StringSink:
37
- """Minimal sys.stdout-shaped target: the wrapper writes strings into us,
38
- we collect them as UTF-8 bytes. Also exposes ``.buffer`` so bytes-path
39
- writes have a path through the wrapper."""
40
-
41
- def __init__(self) -> None:
42
- self.str_bytes = bytearray()
43
- self.buffer = io.BytesIO()
44
- self.name = "test-sink"
45
- self.encoding = "utf-8"
46
- self.errors = "strict"
47
-
48
- def write(self, s: str) -> int:
49
- self.str_bytes.extend(s.encode("utf-8", errors="replace"))
50
- return len(s)
51
-
52
- def flush(self) -> None:
53
- pass
54
-
55
- def captured(self) -> str:
56
- combined = bytes(self.str_bytes) + self.buffer.getvalue()
57
- return combined.decode("utf-8", errors="replace")
58
-
59
-
60
- @pytest.fixture
61
- def wrapper() -> tuple:
62
- """A fresh redactor wrapping a new sink, with an empty token set."""
63
- sc.clear_tokens()
64
- sink = _StringSink()
65
- stream = sc._RedactingStream(sink, "test-stdout") # type: ignore[attr-defined]
66
- yield stream, sink
67
- stream.flush()
68
- sc.clear_tokens()
69
-
70
-
71
- def test_cleartext_is_redacted(wrapper):
72
- stream, sink = wrapper
73
- token = "ghp_abc123abc123abc123"
74
- sc.register_token(token)
75
- stream.write(f"the token was {token} and not noticeable\n")
76
- stream.flush()
77
- text = sink.captured()
78
- assert token not in text
79
- assert "<redacted>" in text
80
- assert "the token was" in text
81
-
82
-
83
- def test_base64_form_is_redacted(wrapper):
84
- stream, sink = wrapper
85
- token = "ghp_abc123abc123abc123"
86
- sc.register_token(token)
87
- encoded = base64.b64encode(token.encode()).decode()
88
- stream.write(f"encoded={encoded}\n")
89
- stream.flush()
90
- text = sink.captured()
91
- assert encoded not in text
92
- assert "<redacted>" in text
93
-
94
-
95
- def test_urlsafe_base64_form_is_redacted(wrapper):
96
- stream, sink = wrapper
97
- token = "some_opaque_secret_for_urlsafe"
98
- sc.register_token(token)
99
- encoded = base64.urlsafe_b64encode(token.encode()).decode()
100
- stream.write(f"encoded={encoded}\n")
101
- stream.flush()
102
- text = sink.captured()
103
- assert encoded not in text
104
- assert "<redacted>" in text
105
-
106
-
107
- def test_url_encoded_form_is_redacted(wrapper):
108
- stream, sink = wrapper
109
- token = "token with spaces & special=chars"
110
- sc.register_token(token)
111
- encoded = urllib.parse.quote(token, safe="")
112
- stream.write(f"in_url={encoded}\n")
113
- stream.flush()
114
- text = sink.captured()
115
- assert encoded not in text
116
- assert "<redacted>" in text
117
-
118
-
119
- def test_hex_form_is_redacted(wrapper):
120
- stream, sink = wrapper
121
- token = "0123456789abcdef01234567"
122
- sc.register_token(token)
123
- encoded = binascii.hexlify(token.encode()).decode()
124
- stream.write(f"hex={encoded}\n")
125
- stream.flush()
126
- text = sink.captured()
127
- assert encoded not in text
128
- assert "<redacted>" in text
129
-
130
-
131
- def test_register_after_first_write_still_redacts_subsequent(wrapper):
132
- stream, sink = wrapper
133
- stream.write("before registration\n")
134
- token = "late_registered_token_value"
135
- sc.register_token(token)
136
- stream.write(f"after {token} registration\n")
137
- stream.flush()
138
- text = sink.captured()
139
- assert "before registration" in text
140
- assert token not in text
141
- assert "<redacted>" in text
142
-
143
-
144
- def test_split_write_across_boundary_is_caught(wrapper):
145
- stream, sink = wrapper
146
- token = "ghp_splitfragmenttokenvalue"
147
- sc.register_token(token)
148
- stream.write(token[:10])
149
- stream.write(token[10:])
150
- stream.write("\n")
151
- stream.flush()
152
- text = sink.captured()
153
- assert token not in text
154
- assert "<redacted>" in text
155
-
156
-
157
- def test_short_token_below_min_len_is_ignored(wrapper):
158
- """Redacting 3-char strings would produce wildcard false-positives."""
159
- stream, sink = wrapper
160
- sc.register_token("AQ")
161
- stream.write("AQ should appear unchanged because AQ is too short to redact\n")
162
- stream.flush()
163
- text = sink.captured()
164
- assert "AQ" in text
165
- assert "<redacted>" not in text
166
-
167
-
168
- def test_bytes_path_through_buffer(wrapper):
169
- stream, sink = wrapper
170
- token = "some_token_value_we_registered"
171
- sc.register_token(token)
172
- # Write bytes through the wrapper — it routes into sink.buffer.
173
- stream.write(b"\x00\x01\x02binary with " + token.encode() + b" embedded\n")
174
- stream.flush()
175
- text = sink.captured()
176
- assert token not in text
177
- assert "<redacted>" in text
178
- assert "binary with" in text
179
-
180
-
181
- def test_clear_tokens_disables_redaction_for_later_writes(wrapper):
182
- stream, sink = wrapper
183
- token = "a_token_that_will_be_cleared_soon"
184
- sc.register_token(token)
185
- stream.write(f"before clear: {token}\n")
186
- sc.clear_tokens()
187
- stream.write(f"after clear: {token}\n")
188
- stream.flush()
189
- text = sink.captured()
190
- assert text.count("<redacted>") == 1
191
- assert text.count(token) == 1
192
-
193
-
194
- def test_register_tokens_plural_is_equivalent(wrapper):
195
- stream, sink = wrapper
196
- sc.register_tokens(["first_registered_token_abc", "second_registered_token_def"])
197
- stream.write("first_registered_token_abc / second_registered_token_def\n")
198
- stream.flush()
199
- text = sink.captured()
200
- assert "first_registered_token_abc" not in text
201
- assert "second_registered_token_def" not in text
202
- assert text.count("<redacted>") >= 2
203
-
204
-
205
- def test_empty_token_is_ignored(wrapper):
206
- stream, sink = wrapper
207
- sc.register_token("")
208
- stream.write("nothing to redact here\n")
209
- stream.flush()
210
- text = sink.captured()
211
- assert "nothing to redact here" in text
212
- assert "<redacted>" not in text
213
-
214
-
215
- def test_no_crash_on_raw_bytes_without_matching_token(wrapper):
216
- stream, sink = wrapper
217
- sc.register_token("something_registered_but_not_present")
218
- stream.write(b"\x00\x01\x02binary bytes\n")
219
- stream.flush()
220
- text = sink.captured()
221
- assert "binary bytes" in text
222
-
223
-
224
- # --- End-to-end: the auto-install path ---------------------------------------
225
- #
226
- # Tests above exercise _RedactingStream directly, which is fine for the
227
- # redaction logic itself but bypasses the sitecustomize auto-install step
228
- # that replaces sys.stdout on interpreter startup. This subprocess test
229
- # proves that step works — a fresh Python process, with PYTHONPATH pointed
230
- # at the module directory and THINKWORK_SANDBOX_SCRUBBER unset, installs
231
- # the wrapper on its own and redacts a registered token before stdout is
232
- # flushed.
233
-
234
-
235
- def test_auto_install_redacts_on_fresh_interpreter(tmp_path):
236
- script = tmp_path / "run.py"
237
- script.write_text(
238
- """
239
- import sys, sitecustomize
240
- sitecustomize.register_token("ghp_autoInstallValueTokenX")
241
- print("auto-install redacts ghp_autoInstallValueTokenX mid-line here")
242
- """.strip()
243
- )
244
- env = os.environ.copy()
245
- # Strip our opt-out so sitecustomize installs on import.
246
- env.pop("THINKWORK_SANDBOX_SCRUBBER", None)
247
- # Prepend the module dir so Python's startup hook finds our
248
- # sitecustomize.py before any installed one.
249
- env["PYTHONPATH"] = _HERE + os.pathsep + env.get("PYTHONPATH", "")
250
- out = subprocess.run(
251
- [sys.executable, str(script)],
252
- env=env,
253
- check=True,
254
- capture_output=True,
255
- text=True,
256
- )
257
- assert "ghp_autoInstallValueTokenX" not in out.stdout
258
- assert "<redacted>" in out.stdout
259
- assert "auto-install redacts" in out.stdout
260
-
261
-
262
- def test_installed_reports_true_after_auto_install(tmp_path):
263
- """Probe ``installed()`` from a fresh interpreter — confirms the startup
264
- hook ran (and set the flag)."""
265
- script = tmp_path / "run.py"
266
- script.write_text("import sitecustomize; print(sitecustomize.installed())")
267
- env = os.environ.copy()
268
- env.pop("THINKWORK_SANDBOX_SCRUBBER", None)
269
- env["PYTHONPATH"] = _HERE + os.pathsep + env.get("PYTHONPATH", "")
270
- out = subprocess.run(
271
- [sys.executable, str(script)],
272
- env=env,
273
- check=True,
274
- capture_output=True,
275
- text=True,
276
- )
277
- assert out.stdout.strip() == "True"
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env bash
2
- ################################################################################
3
- # build_and_push_sandbox_base.sh — build + push the AgentCore sandbox base
4
- # image to the stage's ECR repo. Invoked by CI; also safe to run locally
5
- # once ``thinkwork doctor`` reports green.
6
- #
7
- # Usage (from repo root):
8
- # bash terraform/modules/app/agentcore-code-interpreter/scripts/build_and_push_sandbox_base.sh \
9
- # --stage dev --region us-east-1
10
- #
11
- # The script:
12
- # 1. Reads the ECR repo URL from ``terraform output -raw`` (must be run
13
- # after ``terraform apply`` lands the agentcore-code-interpreter
14
- # module for the target stage).
15
- # 2. docker build the Dockerfile.sandbox-base with the repo root as
16
- # context (so the COPY can reach packages/).
17
- # 3. Tags with the current git SHA (immutable tag per the ECR repo
18
- # config) and ``:latest``.
19
- # 4. docker push both tags after ``aws ecr get-login-password``.
20
- ################################################################################
21
- set -euo pipefail
22
-
23
- STAGE=""
24
- REGION=""
25
-
26
- while [[ $# -gt 0 ]]; do
27
- case "$1" in
28
- --stage) STAGE="$2"; shift 2 ;;
29
- --region) REGION="$2"; shift 2 ;;
30
- *) echo "unknown arg: $1" >&2; exit 2 ;;
31
- esac
32
- done
33
-
34
- : "${STAGE:?--stage is required}"
35
- : "${REGION:?--region is required}"
36
-
37
- # Resolve the repo URL from terraform state. Tolerant: if the caller runs
38
- # this before the module applies, fall back to the deterministic name.
39
- REPO_URL="$(
40
- terraform -chdir="terraform/examples/greenfield" output -raw \
41
- sandbox_base_ecr_repository_url 2>/dev/null \
42
- || echo ""
43
- )"
44
- if [[ -z "$REPO_URL" ]]; then
45
- ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
46
- REPO_URL="${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/thinkwork-${STAGE}-sandbox-base"
47
- fi
48
-
49
- GIT_SHA="$(git rev-parse --short HEAD)"
50
- IMAGE_TAG="${GIT_SHA}"
51
-
52
- echo "[sandbox-base] repo: ${REPO_URL}"
53
- echo "[sandbox-base] tag: ${IMAGE_TAG}"
54
-
55
- # ECR login
56
- aws ecr get-login-password --region "${REGION}" \
57
- | docker login --username AWS --password-stdin "${REPO_URL%/*}"
58
-
59
- # Build with repo root as the context so COPY can reach packages/.
60
- docker build \
61
- --platform=linux/amd64 \
62
- -f terraform/modules/app/agentcore-code-interpreter/Dockerfile.sandbox-base \
63
- -t "${REPO_URL}:${IMAGE_TAG}" \
64
- -t "${REPO_URL}:latest" \
65
- .
66
-
67
- docker push "${REPO_URL}:${IMAGE_TAG}"
68
- docker push "${REPO_URL}:latest"
69
-
70
- echo "[sandbox-base] pushed ${REPO_URL}:${IMAGE_TAG}"
@@ -1,305 +0,0 @@
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
- }
@@ -1,44 +0,0 @@
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
- }