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
@@ -15,6 +15,10 @@ terraform {
15
15
  source = "hashicorp/tls"
16
16
  version = "~> 4.0"
17
17
  }
18
+ random = {
19
+ source = "hashicorp/random"
20
+ version = ">= 3.0"
21
+ }
18
22
  aws = {
19
23
  source = "hashicorp/aws"
20
24
  version = "~> 5.0"
@@ -483,6 +487,34 @@ resource "terraform_data" "n8n_runtime_state_guardrails" {
483
487
  }
484
488
  }
485
489
  }
490
+ # Egress-only SG for the VPC-attached analyst data-path Lambdas
491
+ # (analyst_lambda_vpc_egress). Their whole point is a stable NAT egress IP for
492
+ # external database allowlists; they accept no inbound traffic.
493
+ resource "aws_security_group" "analyst_egress_lambda" {
494
+ count = var.analyst_lambda_vpc_egress ? 1 : 0
495
+
496
+ name_prefix = "thinkwork-${var.stage}-analyst-egress-"
497
+ description = "Egress for VPC-attached analyst data-path Lambdas"
498
+ vpc_id = module.vpc.vpc_id
499
+
500
+ egress {
501
+ from_port = 0
502
+ to_port = 0
503
+ protocol = "-1"
504
+ cidr_blocks = ["0.0.0.0/0"]
505
+ }
506
+
507
+ tags = { Name = "thinkwork-${var.stage}-analyst-egress-lambda-sg" }
508
+
509
+ lifecycle {
510
+ create_before_destroy = true
511
+ precondition {
512
+ condition = length(module.vpc.private_subnet_ids) > 0
513
+ error_message = "analyst_lambda_vpc_egress requires private (NAT-routed) subnets — a Lambda in a public subnet has no internet egress."
514
+ }
515
+ }
516
+ }
517
+
486
518
  resource "aws_security_group" "okf_wiki_lambda" {
487
519
  count = var.okf_wiki_efs_enabled ? 1 : 0
488
520
 
@@ -704,24 +736,35 @@ module "cognito" {
704
736
  stage = var.stage
705
737
  region = var.region
706
738
 
707
- create_cognito = var.create_cognito
708
- existing_user_pool_id = var.existing_user_pool_id
709
- existing_user_pool_arn = var.existing_user_pool_arn
710
- existing_admin_client_id = var.existing_admin_client_id
711
- existing_mobile_client_id = var.existing_mobile_client_id
712
- existing_identity_pool_id = var.existing_identity_pool_id
713
-
714
- google_oauth_client_id = var.google_oauth_client_id
715
- google_oauth_client_secret = var.google_oauth_client_secret
716
- oidc_identity_providers = var.oidc_identity_providers
717
- saml_identity_providers = var.saml_identity_providers
718
- pre_signup_lambda_zip = var.pre_signup_lambda_zip
719
- custom_auth_lambda_zip = var.cognito_custom_auth_lambda_zip
720
- api_auth_secret = var.api_auth_secret
721
- email_source_arn = var.cognito_email_source_arn
722
- from_email_address = var.cognito_from_email_address
723
- reply_to_email_address = var.cognito_reply_to_email_address
724
- invite_email_subject = var.cognito_invite_email_subject
739
+ create_cognito = var.create_cognito
740
+ existing_user_pool_id = var.existing_user_pool_id
741
+ existing_user_pool_arn = var.existing_user_pool_arn
742
+ existing_admin_client_id = var.existing_admin_client_id
743
+ existing_mobile_client_id = var.existing_mobile_client_id
744
+ existing_identity_pool_id = var.existing_identity_pool_id
745
+ existing_auth_route_clients = var.existing_auth_route_clients
746
+
747
+ google_oauth_client_id = var.google_oauth_client_id
748
+ google_oauth_client_secret = var.google_oauth_client_secret
749
+ microsoft_oauth_client_id = var.microsoft_oauth_client_id
750
+ microsoft_oauth_client_secret = var.microsoft_oauth_client_secret
751
+ microsoft_oauth_tenant = var.microsoft_oauth_tenant
752
+ tenant_entra_connections = var.tenant_entra_connections
753
+ oidc_identity_providers = var.oidc_identity_providers
754
+ saml_identity_providers = var.saml_identity_providers
755
+ pre_signup_lambda_zip = var.pre_signup_lambda_zip
756
+ auth_retirement_phase = var.auth_retirement_phase
757
+ custom_auth_lambda_zip = var.cognito_custom_auth_lambda_zip
758
+ custom_auth_lambda_s3_bucket = var.require_lambda_artifacts ? var.lambda_artifact_bucket : ""
759
+ custom_auth_lambda_s3_key = var.require_lambda_artifacts && var.lambda_artifact_bucket != "" ? "${trim(trimspace(var.lambda_artifact_prefix), "/")}/cognito-custom-auth.zip" : ""
760
+ api_auth_secret = var.api_auth_secret
761
+ pre_token_generation_lambda_s3_bucket = var.require_lambda_artifacts ? var.lambda_artifact_bucket : ""
762
+ pre_token_generation_lambda_s3_key = var.require_lambda_artifacts && var.lambda_artifact_bucket != "" ? "${trim(trimspace(var.lambda_artifact_prefix), "/")}/cognito-pre-token-client-deny.zip" : ""
763
+ denied_app_client_ids = var.cognito_denied_app_client_ids
764
+ email_source_arn = var.cognito_email_source_arn
765
+ from_email_address = var.cognito_from_email_address
766
+ reply_to_email_address = var.cognito_reply_to_email_address
767
+ invite_email_subject = var.cognito_invite_email_subject
725
768
  invite_email_message = (
726
769
  var.cognito_invite_email_message != ""
727
770
  ? var.cognito_invite_email_message
@@ -752,8 +795,12 @@ module "cognito" {
752
795
  local.customer_domain_legacy_retired ? [] : (local.legacy_end_user_app_domain != "" ? ["https://${local.legacy_end_user_app_domain}", "https://${local.legacy_end_user_app_domain}/auth/callback"] : []),
753
796
  local.customer_domain_web_enabled ? ["https://${var.customer_domain}", "https://${var.customer_domain}/auth/callback"] : [],
754
797
  local.customer_domain_legacy_retired ? [] : (var.computer_domain != "" ? ["https://${var.computer_domain}", "https://${var.computer_domain}/auth/callback"] : []),
755
- ["http://localhost:5180", "http://localhost:5180/auth/callback"],
756
- var.desktop_callback_urls
798
+ [
799
+ "http://localhost:5180",
800
+ "http://localhost:5180/auth/callback",
801
+ "http://127.0.0.1:5180",
802
+ "http://127.0.0.1:5180/auth/callback",
803
+ ]
757
804
  ))
758
805
  admin_logout_urls = distinct(concat(
759
806
  var.admin_logout_urls,
@@ -761,10 +808,11 @@ module "cognito" {
761
808
  local.customer_domain_legacy_retired ? [] : (local.legacy_end_user_app_domain != "" ? ["https://${local.legacy_end_user_app_domain}"] : []),
762
809
  local.customer_domain_web_enabled ? ["https://${var.customer_domain}"] : [],
763
810
  local.customer_domain_legacy_retired ? [] : (var.computer_domain != "" ? ["https://${var.computer_domain}"] : []),
764
- ["http://localhost:5180"],
765
- var.desktop_callback_urls
811
+ ["http://localhost:5180", "http://127.0.0.1:5180"]
766
812
  ))
767
813
  desktop_callback_urls = var.desktop_callback_urls
814
+ cli_callback_urls = var.cli_callback_urls
815
+ cli_logout_urls = var.cli_logout_urls
768
816
  mobile_callback_urls = var.mobile_callback_urls
769
817
  mobile_logout_urls = var.mobile_logout_urls
770
818
  }
@@ -892,6 +940,7 @@ module "appsync" {
892
940
 
893
941
  stage = var.stage
894
942
  region = var.region
943
+ account_id = var.account_id
895
944
  user_pool_id = module.cognito.user_pool_id
896
945
  subscription_schema = local.subscription_schema
897
946
  }
@@ -940,6 +989,23 @@ resource "tls_private_key" "capability_signing" {
940
989
  algorithm = "ED25519"
941
990
  }
942
991
 
992
+ resource "random_password" "agentcore_proof_oauth_client_secret" {
993
+ count = var.enable_agentcore_multiplayer_proof ? 1 : 0
994
+ length = 48
995
+ special = false
996
+ }
997
+
998
+ check "agentcore_multiplayer_proof_requires_harness" {
999
+ assert {
1000
+ condition = !var.enable_agentcore_multiplayer_proof || (
1001
+ var.enable_agentcore_harness &&
1002
+ can(regex("^[a-z0-9][a-z0-9-]{0,47}$", var.agentcore_multiplayer_proof_tenant_slug)) &&
1003
+ length(distinct(compact([for owner in split(",", var.agentcore_multiplayer_proof_owner_allowlist) : trimspace(owner)]))) >= 2
1004
+ )
1005
+ error_message = "enable_agentcore_multiplayer_proof requires enable_agentcore_harness, an explicit lowercase tenant slug, and at least two explicit distinct proof owner subjects."
1006
+ }
1007
+ }
1008
+
943
1009
  resource "aws_secretsmanager_secret" "capability_signing_key" {
944
1010
  name = "thinkwork/${var.stage}/capability-signing-key"
945
1011
  description = "Ed25519 private key (PKCS8 PEM) signing capability sidecars and manifests (THINK-173)."
@@ -950,15 +1016,40 @@ resource "aws_secretsmanager_secret_version" "capability_signing_key" {
950
1016
  secret_string = tls_private_key.capability_signing.private_key_pem
951
1017
  }
952
1018
 
1019
+ # AppSync subscription tickets use a separate key and domain from capability
1020
+ # envelopes. The authorizer receives only the public key; ticket issuance
1021
+ # resolves the private key by secret name at runtime.
1022
+ resource "tls_private_key" "subscription_ticket_signing" {
1023
+ algorithm = "ED25519"
1024
+ }
1025
+
1026
+ resource "aws_secretsmanager_secret" "subscription_ticket_signing_key" {
1027
+ name = "thinkwork/${var.stage}/subscription-ticket-signing-key"
1028
+ description = "Ed25519 private key signing one-use AppSync subscription tickets."
1029
+ }
1030
+
1031
+ resource "aws_secretsmanager_secret_version" "subscription_ticket_signing_key" {
1032
+ secret_id = aws_secretsmanager_secret.subscription_ticket_signing_key.id
1033
+ secret_string = tls_private_key.subscription_ticket_signing.private_key_pem
1034
+ }
1035
+
953
1036
  module "api" {
954
1037
  source = "../app/lambda-api"
955
1038
 
956
1039
  capability_signing_public_key = tls_private_key.capability_signing.public_key_pem
957
1040
  capability_signing_private_key_secret = aws_secretsmanager_secret.capability_signing_key.name
1041
+ subscription_ticket_signing_key_id = "${var.stage}-subscription-v1"
1042
+ subscription_ticket_public_keys = jsonencode([{
1043
+ keyId = "${var.stage}-subscription-v1"
1044
+ publicKey = tls_private_key.subscription_ticket_signing.public_key_pem
1045
+ }])
1046
+ subscription_ticket_private_key_secret = aws_secretsmanager_secret.subscription_ticket_signing_key.name
958
1047
 
959
- stage = var.stage
960
- account_id = var.account_id
961
- region = var.region
1048
+ stage = var.stage
1049
+ account_id = var.account_id
1050
+ region = var.region
1051
+ auth_retirement_phase = var.auth_retirement_phase
1052
+ auth_migration_recovery_deadline = var.auth_migration_recovery_deadline
962
1053
 
963
1054
  lambda_artifact_bucket = var.lambda_artifact_bucket
964
1055
  lambda_artifact_prefix = var.lambda_artifact_prefix
@@ -1014,6 +1105,24 @@ module "api" {
1014
1105
  analyst_db_cluster_resource_id = module.database.cluster_resource_id
1015
1106
  analyst_policy_source = var.analyst_policy_source
1016
1107
 
1108
+ # Governed autonomy — per-tenant self-extension opt-in allowlist (default off).
1109
+ capability_self_extension_tenants = var.capability_self_extension_tenants
1110
+
1111
+ # THINK-316 U2 — request path receives only Harness invocation. Terraform
1112
+ # owns provisioning/version/endpoint control, avoiding a module cycle and
1113
+ # keeping PassRole/create/update/list out of chat Lambdas.
1114
+ enable_agentcore_harness_invocation = var.enable_agentcore_multiplayer_proof
1115
+
1116
+ # THINK-316 U1 — proof-only assertion/provider handlers remain absent unless
1117
+ # explicitly enabled. The generated secret stays in Terraform sensitive
1118
+ # state and is passed only to the two narrow boundary Lambdas and Identity.
1119
+ enable_agentcore_multiplayer_proof = var.enable_agentcore_multiplayer_proof
1120
+ agentcore_turn_assertion_key_versions = var.agentcore_turn_assertion_key_versions
1121
+ agentcore_turn_assertion_active_key_version = var.agentcore_turn_assertion_active_key_version
1122
+ agentcore_proof_oauth_client_id = "thinkwork-${var.stage}-agentcore-proof"
1123
+ agentcore_proof_oauth_client_secret = var.enable_agentcore_multiplayer_proof ? random_password.agentcore_proof_oauth_client_secret[0].result : ""
1124
+ agentcore_proof_owner_allowlist = var.agentcore_multiplayer_proof_owner_allowlist
1125
+
1017
1126
  # Phase 3 U8b — KMS key + Object Lock mode forwarded as
1018
1127
  # COMPLIANCE_ANCHOR_KMS_KEY_ARN and COMPLIANCE_ANCHOR_OBJECT_LOCK_MODE
1019
1128
  # env vars on the anchor Lambda. The live `_anchor_fn_live` requires
@@ -1043,8 +1152,8 @@ module "api" {
1043
1152
  mobile_client_id = module.cognito.mobile_client_id
1044
1153
  cognito_auth_domain = module.cognito.auth_domain
1045
1154
 
1155
+ appsync_api_id = module.appsync.graphql_api_id
1046
1156
  appsync_api_url = module.appsync.graphql_api_url
1047
- appsync_api_key = module.appsync.graphql_api_key
1048
1157
 
1049
1158
  kb_service_role_arn = module.bedrock_kb.kb_service_role_arn
1050
1159
 
@@ -1061,6 +1170,8 @@ module "api" {
1061
1170
  memory_engine = local.resolved_memory_engine
1062
1171
  okf_efs_subnet_ids = var.okf_wiki_efs_enabled ? local.okf_wiki_subnet_ids : []
1063
1172
  okf_efs_security_group_ids = var.okf_wiki_efs_enabled ? [aws_security_group.okf_wiki_lambda[0].id] : []
1173
+ analyst_egress_subnet_ids = var.analyst_lambda_vpc_egress ? module.vpc.private_subnet_ids : []
1174
+ analyst_egress_security_group_ids = var.analyst_lambda_vpc_egress ? [aws_security_group.analyst_egress_lambda[0].id] : []
1064
1175
  okf_efs_mount_target_ids = var.okf_wiki_efs_enabled ? aws_efs_mount_target.okf_wiki[*].id : []
1065
1176
  okf_efs_file_system_arn = var.okf_wiki_efs_enabled ? aws_efs_file_system.okf_wiki[0].arn : ""
1066
1177
  okf_efs_refresh_access_point_arn = var.okf_wiki_efs_enabled ? aws_efs_access_point.okf_wiki_refresh[0].arn : ""
@@ -1097,12 +1208,14 @@ module "api" {
1097
1208
  deployment_release_manifest_sha256 = var.deployment_release_manifest_sha256
1098
1209
  enable_stripe_billing = var.enable_stripe_billing
1099
1210
  enable_slack_workspace_app = var.enable_slack_workspace_app
1211
+ enable_msteams_app = var.enable_msteams_app
1100
1212
  agentcore_code_interpreter_id = var.agentcore_code_interpreter_id
1101
1213
  wiki_compile_model_id = var.wiki_compile_model_id
1102
1214
  brain_source_agent_model_id = var.brain_source_agent_model_id
1103
1215
  wiki_aggregation_pass_enabled = var.wiki_aggregation_pass_enabled
1104
1216
  wiki_source = var.wiki_source
1105
1217
  knowledge_graph_observations_ingest_enabled = var.knowledge_graph_observations_ingest_enabled
1218
+ ontology_scan_sweep_enabled = var.ontology_scan_sweep_enabled
1106
1219
  wiki_deterministic_linking_enabled = var.wiki_deterministic_linking_enabled
1107
1220
  google_places_api_key = var.google_places_api_key
1108
1221
  enable_workspace_orchestration = var.enable_workspace_orchestration
@@ -1123,6 +1236,18 @@ module "api" {
1123
1236
  mcp_custom_domain = var.mcp_custom_domain
1124
1237
  mcp_custom_domain_ready = var.mcp_custom_domain_ready
1125
1238
 
1239
+ # THINK-280 — sandbox provisioning + capability broker wiring. The admin ARN
1240
+ # + token let graphql-http (createTenant) RequestResponse-invoke the
1241
+ # agentcore-admin Lambda. The four CAPABILITY_BROKER_* values are EMPTY when
1242
+ # the broker is disabled (default), so the broker-session path stays inert.
1243
+ agentcore_admin_lambda_arn = module.agentcore_admin.lambda_arn
1244
+ agentcore_admin_token = module.agentcore_admin.admin_token
1245
+ capability_broker_session_table = module.capability_broker.session_table_name
1246
+ capability_broker_session_table_arn = module.capability_broker.session_table_arn
1247
+ capability_broker_audience = module.capability_broker.broker_audience
1248
+ capability_broker_api_id = module.capability_broker.private_api_id
1249
+ capability_broker_vpce_dns = module.capability_broker.execute_api_vpce_dns_name
1250
+
1126
1251
  depends_on = [module.cognito]
1127
1252
  }
1128
1253
 
@@ -1189,6 +1314,251 @@ module "agentcore_pi" {
1189
1314
  okf_efs_read_access_point_arn = var.okf_wiki_efs_enabled ? aws_efs_access_point.okf_wiki_pi_read[0].arn : ""
1190
1315
  }
1191
1316
 
1317
+ # AgentCore Harness execution role and managed tenant/profile runtime. The
1318
+ # public root inputs retain their rollout-era names until the example-stack
1319
+ # compatibility window closes; this module boundary uses managed semantics.
1320
+ module "agentcore_harness" {
1321
+ source = "../app/agentcore-harness"
1322
+
1323
+ enabled = var.enable_agentcore_harness
1324
+ managed_runtime_enabled = var.enable_agentcore_multiplayer_proof
1325
+ stage = var.stage
1326
+ region = var.region
1327
+ account_id = var.account_id
1328
+ bucket_name = module.s3.bucket_name
1329
+ tenant_slug = var.agentcore_multiplayer_proof_tenant_slug
1330
+ discovery_url = "${module.api.agentcore_turn_assertion_issuer}/.well-known/openid-configuration"
1331
+ harness_audience = module.api.agentcore_harness_audience
1332
+ gateway_arn = module.agentcore_proof_gateway.gateway_arn
1333
+ oauth_credential_provider_arn = module.agentcore_proof_identity.credential_provider_arn
1334
+ oauth_credential_secret_arn = module.agentcore_proof_identity.credential_secret_arn
1335
+ oauth_return_url = module.agentcore_proof_identity.oauth_return_url
1336
+ }
1337
+
1338
+ # The Harness depends on the public issuer/API, so feeding its generated ARN
1339
+ # back into the api module would create a Terraform cycle. Publish the
1340
+ # non-secret, attested readiness contract under deterministic SSM keys; the
1341
+ # runner and DeploymentStatus resolver read it server-side. No browser token,
1342
+ # participant id, credential, prompt, or private result is stored here. Keep
1343
+ # the original address during the migration so deployed runners never lose
1344
+ # their profile between releases.
1345
+ locals {
1346
+ agentcore_harness_profile_value = jsonencode({
1347
+ tenantSlug = var.agentcore_multiplayer_proof_tenant_slug
1348
+ trustProfile = "default"
1349
+ harnessArn = module.agentcore_harness.managed_harness_arn
1350
+ endpointArn = module.agentcore_harness.managed_endpoint_arn
1351
+ endpointName = module.agentcore_harness.managed_endpoint_name
1352
+ expectedVersion = module.agentcore_harness.managed_target_version
1353
+ liveVersion = module.agentcore_harness.managed_live_version
1354
+ modelId = module.agentcore_harness.managed_model_id
1355
+ status = module.agentcore_harness.managed_status
1356
+ configurationFingerprint = module.agentcore_harness.managed_configuration_fingerprint
1357
+ authorizerAudience = module.api.agentcore_harness_audience
1358
+ sessionStrategy = "fresh"
1359
+ gatewayArn = module.agentcore_proof_gateway.gateway_arn
1360
+ gatewayUrl = module.agentcore_proof_gateway.gateway_url
1361
+ gatewayTargetName = module.agentcore_proof_gateway.target_name
1362
+ identityWorkloadName = module.agentcore_proof_identity.workload_identity_name
1363
+ identityCredentialProviderName = module.agentcore_proof_identity.credential_provider_name
1364
+ identityCredentialProviderArn = module.agentcore_proof_identity.credential_provider_arn
1365
+ invocationToolsContract = "control-plane-attested-full-override-v1"
1366
+ invocationToolsFingerprint = module.agentcore_harness.managed_invocation_tools_fingerprint
1367
+ invocationTools = jsondecode(module.agentcore_harness.managed_invocation_tools_json)
1368
+ strategyDecisionRule = "reuse_only_if_correct_and_20_percent_benefit"
1369
+ capacityEnvelope = {
1370
+ activeSessions = 100
1371
+ newSessionsPerSecond = 10
1372
+ minimumHeadroom = 0.50
1373
+ }
1374
+ })
1375
+ }
1376
+
1377
+ resource "aws_ssm_parameter" "agentcore_harness_proof_profile" {
1378
+ count = var.enable_agentcore_multiplayer_proof ? 1 : 0
1379
+
1380
+ name = "/thinkwork/${var.stage}/agentcore-harness-proof-profile"
1381
+ type = "String"
1382
+ # The exact immutable Harness tool schemas sit close to Standard's 4 KiB
1383
+ # ceiling. Intelligent-Tiering stays Standard while possible and safely
1384
+ # promotes only when a legitimate governed schema requires more room.
1385
+ tier = "Intelligent-Tiering"
1386
+ value = local.agentcore_harness_profile_value
1387
+
1388
+ lifecycle {
1389
+ precondition {
1390
+ # Base64 expands every three UTF-8 bytes to four ASCII characters. A
1391
+ # conservative 10,920-character ceiling admits at most 8,190 bytes and
1392
+ # cannot cross SSM's 8 KiB Advanced parameter limit.
1393
+ condition = length(base64encode(local.agentcore_harness_profile_value)) <= 10920
1394
+ error_message = "The AgentCore Harness managed profile exceeds SSM's 8 KiB parameter limit."
1395
+ }
1396
+ }
1397
+
1398
+ tags = {
1399
+ Name = "thinkwork-${var.stage}-agentcore-harness-proof-profile"
1400
+ "thinkwork:proof" = "THINK-316"
1401
+ "thinkwork:tenant" = var.agentcore_multiplayer_proof_tenant_slug
1402
+ "thinkwork:profile" = "default"
1403
+ "thinkwork:visibility" = "server-only-nonsecret"
1404
+ }
1405
+ }
1406
+
1407
+ # Managed per-tenant profile address. Runtime lookup reads this first and only
1408
+ # falls back to the original single-tenant key during the migration window.
1409
+ # Adding the scoped key is non-destructive and lets later tenants receive their
1410
+ # own attested profile without changing Lambda configuration or hot-path
1411
+ # control-plane resources.
1412
+ resource "aws_ssm_parameter" "agentcore_harness_profile" {
1413
+ count = var.enable_agentcore_multiplayer_proof ? 1 : 0
1414
+
1415
+ name = "/thinkwork/${var.stage}/agentcore-harness-profiles/${var.agentcore_multiplayer_proof_tenant_slug}"
1416
+ type = aws_ssm_parameter.agentcore_harness_proof_profile[0].type
1417
+ tier = "Intelligent-Tiering"
1418
+ value = aws_ssm_parameter.agentcore_harness_proof_profile[0].value
1419
+
1420
+ tags = {
1421
+ Name = "thinkwork-${var.stage}-agentcore-harness-profile-${var.agentcore_multiplayer_proof_tenant_slug}"
1422
+ "thinkwork:managed-by" = "terraform"
1423
+ "thinkwork:tenant" = var.agentcore_multiplayer_proof_tenant_slug
1424
+ "thinkwork:profile" = "default"
1425
+ "thinkwork:visibility" = "server-only-nonsecret"
1426
+ }
1427
+ }
1428
+
1429
+ # Publish the new immutable endpoint/profile first, then reclaim older
1430
+ # endpoint versions. Retain the active endpoint plus exactly one prior endpoint
1431
+ # for guarded rollback; the dedicated Harness owns no unrelated endpoints.
1432
+ resource "terraform_data" "agentcore_harness_endpoint_retention" {
1433
+ count = var.enable_agentcore_multiplayer_proof ? 1 : 0
1434
+
1435
+ triggers_replace = {
1436
+ active_endpoint = module.agentcore_harness.managed_endpoint_name
1437
+ profile_digest = module.agentcore_harness.managed_configuration_fingerprint
1438
+ }
1439
+
1440
+ provisioner "local-exec" {
1441
+ command = "bash ${path.module}/../app/agentcore-harness/scripts/prune_harness.sh"
1442
+ environment = {
1443
+ AWS_REGION = var.region
1444
+ HARNESS_ID = module.agentcore_harness.managed_harness_id
1445
+ ACTIVE_ENDPOINT_NAME = module.agentcore_harness.managed_endpoint_name
1446
+ ENDPOINT_PREFIX = "ThinkworkProofV"
1447
+ LEGACY_ENDPOINT_NAME = "ThinkworkProof"
1448
+ }
1449
+ }
1450
+
1451
+ depends_on = [
1452
+ aws_ssm_parameter.agentcore_harness_proof_profile,
1453
+ aws_ssm_parameter.agentcore_harness_profile,
1454
+ ]
1455
+ }
1456
+
1457
+ # THINK-316 U1 proof-only Identity and Gateway plane. These resources use the
1458
+ # regional execute-api URL because the dev account rejects public Lambda
1459
+ # Function URLs and a custom domain may be unavailable in a fresh stage.
1460
+ module "agentcore_proof_identity" {
1461
+ source = "../app/agentcore-identity"
1462
+
1463
+ enabled = var.enable_agentcore_multiplayer_proof
1464
+ stage = var.stage
1465
+ region = var.region
1466
+ account_id = var.account_id
1467
+ oauth_issuer = module.api.agentcore_proof_oauth_issuer
1468
+ oauth_client_id = "thinkwork-${var.stage}-agentcore-proof"
1469
+ oauth_client_secret = var.enable_agentcore_multiplayer_proof ? random_password.agentcore_proof_oauth_client_secret[0].result : ""
1470
+ user_federation_return_urls = [
1471
+ "${module.api.api_endpoint}/api/skills/mcp-oauth/agentcore/complete",
1472
+ ]
1473
+ }
1474
+
1475
+ module "agentcore_proof_gateway" {
1476
+ source = "../app/agentcore-gateway"
1477
+
1478
+ enabled = var.enable_agentcore_multiplayer_proof
1479
+ stage = var.stage
1480
+ region = var.region
1481
+ account_id = var.account_id
1482
+ discovery_url = "${module.api.agentcore_turn_assertion_issuer}/.well-known/openid-configuration"
1483
+ gateway_audience = module.api.agentcore_gateway_audience
1484
+ target_base_url = module.api.agentcore_proof_target_base_url
1485
+ oauth_credential_provider_arn = module.agentcore_proof_identity.credential_provider_arn
1486
+ oauth_credential_secret_arn = module.agentcore_proof_identity.credential_secret_arn
1487
+ oauth_return_url = module.agentcore_proof_identity.oauth_return_url
1488
+ proof_owner_allowlist = var.agentcore_multiplayer_proof_owner_allowlist
1489
+ }
1490
+
1491
+ # Capability Broker (THINK-280 U3) — ship-inert, gated by
1492
+ # var.enable_capability_broker (default false). When off, this module creates
1493
+ # nothing; the broker Lambda code also fails closed. Owns a DEDICATED
1494
+ # execute-api VPCE with private DNS disabled — never folded into
1495
+ # okf_wiki_interface_endpoint_services (THINK-144).
1496
+ module "capability_broker" {
1497
+ source = "../app/capability-broker"
1498
+
1499
+ enabled = var.enable_capability_broker
1500
+ stage = var.stage
1501
+ account_id = var.account_id
1502
+ region = var.region
1503
+
1504
+ vpc_id = module.vpc.vpc_id
1505
+ vpc_cidr_block = module.vpc.vpc_cidr_block
1506
+ subnet_ids = local.okf_wiki_subnet_ids
1507
+
1508
+ db_cluster_arn = module.database.db_cluster_arn
1509
+ db_secret_arn = module.database.graphql_db_secret_arn
1510
+ db_cluster_endpoint = module.database.cluster_endpoint
1511
+ db_password = var.db_password
1512
+ database_name = var.database_name
1513
+
1514
+ lambda_zips_dir = var.lambda_zips_dir
1515
+ lambda_artifact_bucket = var.lambda_artifact_bucket
1516
+ lambda_artifact_prefix = var.lambda_artifact_prefix
1517
+ }
1518
+
1519
+ # AgentCore Code Interpreter substrate (THINK-280). Stage-level ECR repo +
1520
+ # per-tenant IAM policy templates the agentcore-admin Lambda consumes. The
1521
+ # capability-private VPC placement passes through from the broker outputs —
1522
+ # EMPTY lists when the broker is disabled, so the capability-private path stays
1523
+ # inert while the regular public/internal sandbox substrate deploys.
1524
+ module "agentcore_code_interpreter" {
1525
+ source = "../app/agentcore-code-interpreter"
1526
+
1527
+ stage = var.stage
1528
+ region = var.region
1529
+ account_id = var.account_id
1530
+
1531
+ capability_private_subnet_ids = module.capability_broker.capability_private_interpreter_subnet_ids
1532
+ capability_private_security_group_ids = module.capability_broker.capability_private_interpreter_security_group_id != "" ? [module.capability_broker.capability_private_interpreter_security_group_id] : []
1533
+ }
1534
+
1535
+ # AgentCore Admin control-plane Lambda (THINK-280). Regular sandbox provisioning
1536
+ # (createTenant → invokeProvisionTenantSandbox) depends on this Lambda; it was
1537
+ # previously instantiated nowhere. Dedicated least-privilege role. The
1538
+ # capability-private env is EMPTY when the broker is disabled → the handler
1539
+ # skips capability-private provisioning (ship-inert).
1540
+ module "agentcore_admin" {
1541
+ source = "../app/agentcore-admin"
1542
+
1543
+ stage = var.stage
1544
+ region = var.region
1545
+ account_id = var.account_id
1546
+
1547
+ lambda_zips_dir = var.lambda_zips_dir
1548
+ lambda_artifact_bucket = var.lambda_artifact_bucket
1549
+ lambda_artifact_prefix = var.lambda_artifact_prefix
1550
+
1551
+ # db_username defaults to the aurora-postgres master username
1552
+ # ("thinkwork_admin") — same default lambda-api relies on.
1553
+ db_password = var.db_password
1554
+ db_cluster_endpoint = module.database.cluster_endpoint
1555
+ database_name = var.database_name
1556
+ graphql_db_secret_arn = module.database.graphql_db_secret_arn
1557
+
1558
+ capability_private_subnet_ids = module.agentcore_code_interpreter.capability_private_subnet_ids
1559
+ capability_private_security_group_ids = module.agentcore_code_interpreter.capability_private_security_group_ids
1560
+ }
1561
+
1192
1562
  # Runtime identity rename: the former dedicated Flue module is now the Pi
1193
1563
  # module. Move existing state to the renamed module/resource addresses so the
1194
1564
  # deployed Lambda, role, log group, and invoke config are updated in place.