diff --git a/CHANGELOG.md b/CHANGELOG.md index d8adfde2..34caa11e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,23 @@ All notable changes to this project are documented in this file. Format follows For narrative release notes written for operators and product owners, see [RELEASE_NOTES.md](RELEASE_NOTES.md). +## [1.4.0] - 2026-07-10 + +Opt-in MCP user-identity forwarding, plus an admin OAuth-provider repair. A new Cognito Pre-Token-Generation Lambda can copy configured user-pool attributes into namespaced claims on the access token β€” the only token forwarded end-to-end to MCP servers β€” so personalized MCP tools can identify the caller. It ships disabled by default (a fork that configures nothing gets zero resources). Also fixes a 502 when adding the first admin OAuth provider. A platform (CDK) deploy is required for the OAuth-provider IAM fix. + +### πŸš€ Added + +- MCP user identity forwarding: an opt-in Cognito Pre-Token-Generation v2 Lambda copies configured user-pool attributes into namespaced claims on the access token forwarded to MCP servers, so personalized MCP tools can identify the caller β€” no changes to the SPA β†’ app-api β†’ inference-api β†’ MCP path, since the access token was already the token forwarded end to end. Fail-open (any handler error returns the event unchanged, so login is never blocked) and stdlib-only. Enabling requires the Cognito Essentials feature plan plus `CDK_MCP_TOKEN_ENRICHMENT_ENABLED` + `CDK_MCP_TOKEN_ENRICHMENT_CLAIMS`; disabled by default (#627) + +### πŸ› Fixed + +- Admin "add OAuth provider" (`POST /admin/oauth-providers/`) returned a 502 Bad Gateway on the first provider create. AgentCore's `CreateOauth2CredentialProvider` lazily ensures the default token vault exists, which requires `bedrock-agentcore:CreateTokenVault` (+ `GetTokenVault`) on the caller β€” grants the app-api task role was missing, so the AccessDenied surfaced as a 502 via the shared AWS-ClientError handler. Both actions are added to the `AgentCoreWorkloadIdentityAccess` statement (#628) + +### πŸ—οΈ Infrastructure + +- New opt-in `token-enrichment` Lambda (real-code `fromAsset`, attached to the user pool via Cognito `addTrigger` `V2_0`) wired conditionally into `PlatformStack`; the pool's `featurePlan` is pinned to `ESSENTIALS`. Inert unless `CDK_MCP_TOKEN_ENRICHMENT_ENABLED=true` β€” the committed `cdk.context.json` stays inactive (#627) +- app-api task role: `bedrock-agentcore:CreateTokenVault` + `GetTokenVault` added to the `AgentCoreWorkloadIdentityAccess` statement (scope `token-vault/*` already covered `token-vault/default`; only the actions were missing) (#628) + ## [1.3.0] - 2026-07-10 Bedrock Mantle expansion and an API-key endpoint repair. Mantle models gain declarative per-model `apiMode` (Chat Completions vs Responses API) and `region` fields on Strands' `bedrock_mantle_config`, unlocking Responses-only models like `openai.gpt-5.x`; the API-key `POST /chat/api-converse` endpoint β€” broken in cloud since the BFF/runtime migrations β€” is relocated onto app-api and now serves the full model catalog including Mantle. Plus Memory Spaces and Scheduled Runs follow-ups. No breaking changes; a platform (CDK) deploy is required for two app-api IAM grants. diff --git a/README.md b/README.md index ff4ffab3..88054135 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ **An open-source, production-ready Generative AI platform for institutions** *Built by Boise State University, designed for everyone.* -[![Release](https://img.shields.io/badge/Release-v1.3.0-6366f1?style=flat&logo=github&logoColor=white)](RELEASE_NOTES.md) +[![Release](https://img.shields.io/badge/Release-v1.4.0-6366f1?style=flat&logo=github&logoColor=white)](RELEASE_NOTES.md) [![Nightly](https://github.com/Boise-State-Development/agentcore-public-stack/actions/workflows/nightly.yml/badge.svg)](https://github.com/Boise-State-Development/agentcore-public-stack/actions/workflows/nightly.yml) ![Python](https://img.shields.io/badge/Python-3.13+-3776AB?style=flat&logo=python&logoColor=white) @@ -296,7 +296,7 @@ agentcore-public-stack/ See [RELEASE_NOTES.md](RELEASE_NOTES.md) for the full changelog, including new features, bug fixes, platform upgrades, and deployment notes for each release. -**Current release:** v1.3.0 +**Current release:** v1.4.0 --- diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a3acebd1..2e07bd2c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,52 @@ +# Release Notes β€” v1.4.0 + +**Release Date:** July 10, 2026 +**Previous Release:** v1.3.0 (July 10, 2026) + +--- + +> πŸ—οΈ **This release requires a platform (CDK) deploy** β€” the app-api task role gains two token-vault IAM grants that fix the admin OAuth-provider 502. No data migration, no breaking changes. The new MCP identity-forwarding feature ships **disabled**: enabling it is opt-in and creates a Lambda + pins the Cognito feature plan, so operators who do nothing are unaffected β€” see the Deployment notes. + +--- + +## Highlights + +v1.4.0 adds opt-in **MCP user identity forwarding** and repairs the admin **OAuth-provider** flow. A new Cognito Pre-Token-Generation Lambda can copy configured user-pool attributes into namespaced claims on the access token β€” the only token forwarded end-to-end to MCP servers β€” so a personalized MCP tool can identify the calling user without touching the SPA β†’ app-api β†’ inference-api β†’ MCP forwarding path. The feature is disabled by default; a fork that configures nothing gets zero new resources. Separately, adding the first admin OAuth provider returned a 502 Bad Gateway because the app-api task role lacked the token-vault permissions AgentCore needs to lazily create the default vault β€” now granted. + +## MCP user identity forwarding + +Personalized MCP tools need to know *who* is calling, but the access token forwarded to MCP servers carried no user attributes. This release adds an opt-in Cognito Pre-Token-Generation v2 trigger that enriches the access token with configured user-pool attributes as namespaced claims β€” so downstream MCP tools can identify the caller, with no changes to the token-forwarding path (the access token was already the token carried end to end). + +### Backend + +- **Fail-open enrichment handler (#627)** β€” `infrastructure/lambda-assets/token-enrichment/handler.py`, a stdlib-only Pre-Token-Generation v2 Lambda. It copies the configured user-pool attributes into namespaced claims on the **access** token. Any error returns the event unchanged, so a misconfiguration can never block login. Covered by `test_handler.py` (244 lines). + +### Infrastructure + +- **Config surface (#627)** β€” `McpIdentityConfig` (`infrastructure/lib/config.ts`): `enabled` plus an `accessTokenClaims` map, settable via the `CDK_MCP_TOKEN_ENRICHMENT_CLAIMS` JSON env var or CDK context (new `parseJsonRecordEnv` helper). +- **Conditional construct (#627)** β€” `token-enrichment-construct.ts` builds the real-code Lambda (`fromAsset`) and attaches it via Cognito `addTrigger` `V2_0`; the user pool's `featurePlan` is pinned to `ESSENTIALS` (a prerequisite of Pre-Token-Gen v2). Wired into `PlatformStack` only when `CDK_MCP_TOKEN_ENRICHMENT_ENABLED=true`, with job-level env in `platform.yml`. A fork that sets nothing gets zero resources and the committed `cdk.context.json` stays inert. + +### Test Coverage + +244+ lines of new handler tests plus the spec's resolved open questions and an implementation summary (`docs/specs/MCP_USER_IDENTITY_FORWARDING_SPEC.md`, `MCP_USER_IDENTITY_FORWARDING_IMPLEMENTATION.md`), including the mcp-servers follow-on handoff. + +## πŸ› Bug fixes + +- **Adding the first admin OAuth provider returned a 502 (#628).** `POST /admin/oauth-providers/` failed with a 502 Bad Gateway. The real cause, from dev-ai app-api logs, was an `AccessDeniedException` on `bedrock-agentcore:CreateTokenVault` against `token-vault/default`: AgentCore's `CreateOauth2CredentialProvider` lazily ensures the default token vault exists on the first provider create, which requires `CreateTokenVault` (+ `GetTokenVault`) on the caller. The app-api task role had the `...Oauth2CredentialProvider` actions but not the token-vault ones, and the shared handler maps an uncaught AWS `ClientError` to HTTP 502 β€” so a missing permission surfaced as a 502 rather than a 403. Both actions are added to the `AgentCoreWorkloadIdentityAccess` statement (the `token-vault/*` scope already covered `token-vault/default`; only the actions were missing). + +## πŸ—οΈ Infrastructure + +- **New opt-in `token-enrichment` Lambda (#627)** β€” attached to the Cognito user pool as a Pre-Token-Generation v2 trigger; pins the pool `featurePlan` to `ESSENTIALS`. Created only when `CDK_MCP_TOKEN_ENRICHMENT_ENABLED=true`. +- **app-api task role token-vault grants (#628)** β€” `bedrock-agentcore:CreateTokenVault` + `GetTokenVault` added to `AgentCoreWorkloadIdentityAccess`. + +## πŸš€ Deployment notes + +- **A platform (CDK) deploy is required** for the OAuth-provider fix (#628) to take effect β€” it is an IAM change on the app-api task role. Until redeployed, adding the first admin OAuth provider will keep returning a 502. +- **MCP identity forwarding is off unless you opt in (#627).** To enable it: pin the Cognito **Essentials** feature plan on the user pool, then set `CDK_MCP_TOKEN_ENRICHMENT_ENABLED=true` and `CDK_MCP_TOKEN_ENRICHMENT_CLAIMS` (the attributeβ†’claim map) as GitHub Actions variables and redeploy `platform.yml`. Doing nothing leaves the token forwarded exactly as before, with no new resources. +- No data migration, no breaking changes. + +--- + # Release Notes β€” v1.3.0 **Release Date:** July 10, 2026 diff --git a/VERSION b/VERSION index f0bb29e7..e21e727f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.0 +1.4.0 \ No newline at end of file diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c4f49c4b..15b3b849 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "agentcore-stack" -version = "1.3.0" +version = "1.4.0" requires-python = ">=3.10" description = "Multi-agent conversational AI system with AWS Bedrock AgentCore" readme = "README.md" diff --git a/backend/uv.lock b/backend/uv.lock index 98e74f01..25fd970e 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -12,7 +12,7 @@ resolution-markers = [ [[package]] name = "agentcore-stack" -version = "1.3.0" +version = "1.4.0" source = { editable = "." } dependencies = [ { name = "aiofiles" }, diff --git a/frontend/ai.client/package-lock.json b/frontend/ai.client/package-lock.json index 6a60694e..8562e0af 100644 --- a/frontend/ai.client/package-lock.json +++ b/frontend/ai.client/package-lock.json @@ -1,12 +1,12 @@ { "name": "ai.client", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ai.client", - "version": "1.3.0", + "version": "1.4.0", "dependencies": { "@angular/cdk": "21.2.14", "@angular/common": "21.2.17", diff --git a/frontend/ai.client/package.json b/frontend/ai.client/package.json index cebfc050..4a31510c 100644 --- a/frontend/ai.client/package.json +++ b/frontend/ai.client/package.json @@ -1,6 +1,6 @@ { "name": "ai.client", - "version": "1.3.0", + "version": "1.4.0", "scripts": { "ng": "ng", "start": "ng serve", diff --git a/infrastructure/package-lock.json b/infrastructure/package-lock.json index a8446ecc..6657d138 100644 --- a/infrastructure/package-lock.json +++ b/infrastructure/package-lock.json @@ -1,12 +1,12 @@ { "name": "infrastructure", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "infrastructure", - "version": "1.3.0", + "version": "1.4.0", "dependencies": { "aws-cdk-lib": "2.260.0", "constructs": "10.6.0" diff --git a/infrastructure/package.json b/infrastructure/package.json index bf9ddf05..ba185627 100644 --- a/infrastructure/package.json +++ b/infrastructure/package.json @@ -1,6 +1,6 @@ { "name": "infrastructure", - "version": "1.3.0", + "version": "1.4.0", "bin": { "infrastructure": "bin/infrastructure.js" },