From 5e0cddb16a34ac0c34fb2322d7aa1d7273deff6d Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Fri, 18 Sep 2026 20:30:17 +0000 Subject: [PATCH 1/8] feat(payment): add connector credential rotation to Core --- src/core/payment.tsx | 12 ++++++++++++ src/handlers/payment/types.tsx | 6 ++++++ src/testing/TestCoreClient.tsx | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/src/core/payment.tsx b/src/core/payment.tsx index 58a4bc72d6..045097f100 100644 --- a/src/core/payment.tsx +++ b/src/core/payment.tsx @@ -3,10 +3,13 @@ import { GetPaymentManagerCommand, ListPaymentConnectorsCommand, ListPaymentManagersCommand, + RotatePaymentConnectorCredentialsCommand, type GetPaymentConnectorResponse, type GetPaymentManagerResponse, type ListPaymentConnectorsResponse, type ListPaymentManagersResponse, + type RotatePaymentConnectorCredentialsRequest, + type RotatePaymentConnectorCredentialsResponse, } from "@aws-sdk/client-bedrock-agentcore-control"; import { GetPaymentInstrumentBalanceCommand, @@ -85,6 +88,15 @@ export class PaymentClient implements CorePaymentClient { ); } + async rotatePaymentConnectorCredentials( + request: RotatePaymentConnectorCredentialsRequest, + options: CoreOptions, + ): Promise { + return this.clients + .control(toClientConfig(options)) + .send(new RotatePaymentConnectorCredentialsCommand(request)); + } + // ─── payment sessions (data plane) ────────────────────────────────────────── async getPaymentSession( diff --git a/src/handlers/payment/types.tsx b/src/handlers/payment/types.tsx index 7456a53894..f15275d28b 100644 --- a/src/handlers/payment/types.tsx +++ b/src/handlers/payment/types.tsx @@ -3,6 +3,8 @@ import type { GetPaymentManagerResponse, ListPaymentConnectorsResponse, ListPaymentManagersResponse, + RotatePaymentConnectorCredentialsRequest, + RotatePaymentConnectorCredentialsResponse, } from "@aws-sdk/client-bedrock-agentcore-control"; import type { GetPaymentInstrumentRequest, @@ -45,6 +47,10 @@ export interface CorePaymentClient { maxResults: number | undefined, options: CoreOptions, ): Promise; + rotatePaymentConnectorCredentials( + request: RotatePaymentConnectorCredentialsRequest, + options: CoreOptions, + ): Promise; // Core resolves the selected manager ID to the ARN required by the data plane. getPaymentSession( diff --git a/src/testing/TestCoreClient.tsx b/src/testing/TestCoreClient.tsx index 56d97b7355..2352073984 100644 --- a/src/testing/TestCoreClient.tsx +++ b/src/testing/TestCoreClient.tsx @@ -33,6 +33,7 @@ import type { GetPaymentManagerResponse, ListPaymentConnectorsResponse, ListPaymentManagersResponse, + RotatePaymentConnectorCredentialsResponse, ListAgentRuntimeEndpointsResponse, ListAgentRuntimesResponse, ListAgentRuntimeVersionsResponse, @@ -1579,6 +1580,9 @@ export class TestPaymentClient implements CorePaymentClient { async listPaymentConnectors(): Promise { throw new Error("Unexpected payment call"); } + async rotatePaymentConnectorCredentials(): Promise { + throw new Error("Unexpected payment call"); + } async getPaymentSession(): Promise { throw new Error("Unexpected payment call"); } From 4f874bb115b14531e02a97ab01215983b983c38a Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Fri, 18 Sep 2026 20:31:57 +0000 Subject: [PATCH 2/8] feat(payment): expose connector credential rotation command --- src/handlers/payment/connector/index.tsx | 4 +- .../connector/rotate-credentials/index.tsx | 39 +++++++++ src/handlers/payment/payment.read.test.tsx | 84 +++++++++++++++---- 3 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 src/handlers/payment/connector/rotate-credentials/index.tsx diff --git a/src/handlers/payment/connector/index.tsx b/src/handlers/payment/connector/index.tsx index 75a13a8fc9..2c50a2237e 100644 --- a/src/handlers/payment/connector/index.tsx +++ b/src/handlers/payment/connector/index.tsx @@ -4,10 +4,12 @@ import { renderTui } from "../../../tui"; import type { Core } from "../../types"; import { createGetPaymentConnectorHandler } from "./get"; import { createListPaymentConnectorsHandler } from "./list"; +import { createRotatePaymentConnectorCredentialsHandler } from "./rotate-credentials"; export function createPaymentConnectorHandler(core: Core, io: AppIO): Router { return new Router("connector", "manage connectors under a payment manager") .default(renderTui(core, io)) .handler(createGetPaymentConnectorHandler(core)) - .handler(createListPaymentConnectorsHandler(core)); + .handler(createListPaymentConnectorsHandler(core)) + .handler(createRotatePaymentConnectorCredentialsHandler(core)); } diff --git a/src/handlers/payment/connector/rotate-credentials/index.tsx b/src/handlers/payment/connector/rotate-credentials/index.tsx new file mode 100644 index 0000000000..176e6204cb --- /dev/null +++ b/src/handlers/payment/connector/rotate-credentials/index.tsx @@ -0,0 +1,39 @@ +import { CoinbaseCdpSecret } from "@aws-sdk/client-bedrock-agentcore-control"; +import z from "zod"; +import { createHandler, flag } from "../../../../router"; +import { JsonRendererKey } from "../../../../tui"; +import type { Core } from "../../../types"; +import { coreOptsFromCtx } from "../../../utils"; + +export const createRotatePaymentConnectorCredentialsHandler = (core: Core) => + createHandler({ + name: "rotate-credentials", + description: "rotate service-managed credentials for a Quick Create Coinbase connector", + flags: [ + flag("manager-id", "the parent payment manager ID", z.string().min(1)), + flag("connector-id", "the payment connector ID", z.string().min(1)), + flag( + "secrets", + "credential kinds to rotate: API_KEY, WALLET_SECRET, or both (not secret values)", + z + .array(z.enum(CoinbaseCdpSecret)) + .min(1) + .refine((secrets) => new Set(secrets).size === secrets.length, { + message: "credential selections must be unique", + }), + ), + flag("client-token", "idempotency token for this request", z.string().optional()), + ], + handle: async (ctx, flags) => { + const response = await core.payment.rotatePaymentConnectorCredentials( + { + paymentManagerId: flags["manager-id"], + paymentConnectorId: flags["connector-id"], + credentialsToRotate: { coinbaseCDP: { secrets: flags.secrets } }, + clientToken: flags["client-token"], + }, + coreOptsFromCtx(ctx), + ); + ctx.require(JsonRendererKey).renderJson(response); + }, + }); diff --git a/src/handlers/payment/payment.read.test.tsx b/src/handlers/payment/payment.read.test.tsx index 59a2017c9a..ef4fc4b9c5 100644 --- a/src/handlers/payment/payment.read.test.tsx +++ b/src/handlers/payment/payment.read.test.tsx @@ -19,6 +19,14 @@ const INSTRUMENT_CONNECTOR_ID = "mycdpconnectoraidandal-okve8guw4y"; const SESSION_ID = "payment-session-nq812U4e1BJIfw1"; const INSTRUMENT_ID = "payment-instrument-CG2Tl7U1HnCGfHW"; const scope = ["--manager-id", MANAGER_ID, "--user-id", "agentcore-cli-e2e"]; +const rotationArgs = [ + "connector", + "rotate-credentials", + "--manager-id", + MANAGER_ID, + "--connector-id", + CONNECTOR_ID, +]; function setup(resource = "manager", overrides: Partial> = {}) { const core = new CoreClient({ @@ -42,7 +50,7 @@ function setup(resource = "manager", overrides: Partial { +test("registers the payment command tree without TUI leaves", () => { const payment = compile(setup().root, ValueContext.EmptyContext()).commands.find( (c) => c.name() === "payment", )!; @@ -52,7 +60,7 @@ test("registers the read-only command tree without TUI or mutation leaves", () = ), ).toEqual({ manager: ["get", "list"], - connector: ["get", "list"], + connector: ["get", "list", "rotate-credentials"], session: ["get", "list"], instrument: ["get", "list", "balance"], }); @@ -61,6 +69,48 @@ test("registers the read-only command tree without TUI or mutation leaves", () = } }); +test.each([ + { secrets: ["API_KEY"], clientToken: undefined }, + { secrets: ["WALLET_SECRET"], clientToken: "rotate-wallet" }, + { secrets: ["API_KEY", "WALLET_SECRET"], clientToken: "rotate-both" }, +])("rotates the selected connector credentials: %j", async ({ secrets, clientToken }) => { + const response = { + paymentManagerId: MANAGER_ID, + paymentConnectorId: CONNECTOR_ID, + status: "READY", + lastUpdatedAt: new Date("2026-09-18T00:00:00.000Z"), + }; + const send = mock(async (_command: { input: unknown }) => response); + const createControlClient = mock(() => ({ send }) as never); + const { run, io } = setup("connector", { createControlClient }); + await run([ + ...rotationArgs, + "--secrets", + ...secrets, + ...(clientToken ? ["--client-token", clientToken] : []), + "--endpoint-url", + "https://control.example.test", + "--json", + ]); + expect(createControlClient).toHaveBeenCalledWith({ + region: "us-west-2", + endpoint: "https://control.example.test", + }); + expect(send).toHaveBeenCalledTimes(1); + const command = send.mock.calls[0]![0]; + expect(command.constructor.name).toBe("RotatePaymentConnectorCredentialsCommand"); + expect(command.input).toEqual({ + paymentManagerId: MANAGER_ID, + paymentConnectorId: CONNECTOR_ID, + credentialsToRotate: { coinbaseCDP: { secrets } }, + clientToken, + }); + expect(JSON.parse(io.stdout())).toEqual({ + ...response, + lastUpdatedAt: response.lastUpdatedAt.toISOString(), + }); +}); + test.each([ ["manager", "get", ["--id", "mypaymentmanager-o4ks3qfgtb"]], ["manager", "list", []], @@ -180,6 +230,9 @@ test.each([ ["instrument", "get", ...scope, "--instrument-id", INSTRUMENT_ID, "--manager-arn", "arn:old"], "unknown option", ], + [rotationArgs, "--secrets"], + [[...rotationArgs, "--secrets", "INVALID"], "Invalid value for option '--secrets'"], + [[...rotationArgs, "--secrets", "API_KEY", "API_KEY"], "must be unique"], ] as const)("rejects incomplete or obsolete selectors: %j", async (args, message) => { await expect(setup().run([...args])).rejects.toThrow(message); }); @@ -197,16 +250,17 @@ test.each([ await expect(run(["session", "list", ...scope])).rejects.toThrow(message); }); -test.each(["createControlClient", "createDataClient"] as const)( - "preserves a payment service failure from %s", - async (factory) => { - const error = new Error("Payment request denied"); - const send = mock(async () => { - throw error; - }); - const { run, io } = setup("session", { [factory]: () => ({ send }) as never }); - await expect(run(["session", "list", ...scope])).rejects.toBe(error); - expect(send).toHaveBeenCalledTimes(1); - expect(io.stdout()).toBe(""); - }, -); +test.each([ + ["createControlClient", ["session", "list", ...scope]], + ["createDataClient", ["session", "list", ...scope]], + ["createControlClient", [...rotationArgs, "--secrets", "API_KEY"]], +] as const)("preserves a payment service failure from %s for %j", async (factory, args) => { + const error = new Error("Payment request denied"); + const send = mock(async () => { + throw error; + }); + const { run, io } = setup("session", { [factory]: () => ({ send }) as never }); + await expect(run([...args])).rejects.toBe(error); + expect(send).toHaveBeenCalledTimes(1); + expect(io.stdout()).toBe(""); +}); From 4e167d6509d7859bbaf6d22b577a26121a9a953e Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Fri, 18 Sep 2026 20:33:35 +0000 Subject: [PATCH 3/8] docs(payment): describe managed credential rotation --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index f3068675bb..7420f328dc 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,27 @@ One-shot commands return JSON output, status, exit code, and session ID. Escape interrupts the local stream, not necessarily the remote process. Use `runtime shell` for a native interactive terminal. +### Rotate Payment Connector Credentials + +Only READY Coinbase Quick Create connectors support credential rotation. +`--secrets` selects `API_KEY`, `WALLET_SECRET`, or both; it does not accept secret +values. Rotation uses the connector's existing consent and the caller's +control-plane IAM permissions, without an application user ID. + +```bash +agentcore payment connector rotate-credentials \ + --manager-id "$MANAGER_ID" --connector-id "$CONNECTOR_ID" \ + --secrets API_KEY WALLET_SECRET +``` + +The service performs the rotation and returns its result. An optional +`--client-token` identifies retries of the same request. + +Wallet-secret rotation can interrupt wallet operations while the new credential +is installed. Selecting both credentials rotates the API key first, then the +wallet secret; this is not atomic. An error does not guarantee that credentials +are unchanged. + ## Extending the CDK app `agentcore/cdk/` has two source files. `bin/cdk.ts` reads the project once From 4e665c74468d0af2fc15e1a4be277b3737bf34b1 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 30 Sep 2026 15:10:19 +0000 Subject: [PATCH 4/8] fix(payment): use the published credential rotation SDK --- bun.lock | 48 +++++++++++++++++++++- package.json | 2 +- src/handlers/payment/payment.read.test.tsx | 3 -- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/bun.lock b/bun.lock index 0ef34dcb1c..8cc361b531 100644 --- a/bun.lock +++ b/bun.lock @@ -9,7 +9,7 @@ "@aws-sdk/client-application-signals": "^3.1092.0", "@aws-sdk/client-bedrock-agent": "^3.1092.0", "@aws-sdk/client-bedrock-agentcore": "^3.1135.0", - "@aws-sdk/client-bedrock-agentcore-control": "^3.1129.0", + "@aws-sdk/client-bedrock-agentcore-control": "^3.1143.0", "@aws-sdk/client-cloudformation": "^3.1092.0", "@aws-sdk/client-cloudwatch-logs": "^3.1092.0", "@aws-sdk/client-iam": "^3.1080.0", @@ -105,7 +105,7 @@ "@aws-sdk/client-bedrock-agentcore": ["@aws-sdk/client-bedrock-agentcore@3.1136.0", "", { "dependencies": { "@aws-sdk/core": "^3.978.0", "@aws-sdk/credential-provider-node": "^3.972.83", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-fpyMhUO8FMqtsJv4+2b6iE/vkSI2arraWdqo8FOYGnkeLfwtikao3QOwqiNj1ihZ0wk7xr+Sscg5M1wigQEMFw=="], - "@aws-sdk/client-bedrock-agentcore-control": ["@aws-sdk/client-bedrock-agentcore-control@3.1131.0", "", { "dependencies": { "@aws-sdk/core": "^3.978.0", "@aws-sdk/credential-provider-node": "^3.972.83", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-syVIB7YMmMm2LAfpCNh03geBsRh/XBbeTXurDP0a/y5FcKw35yAdsYiZgfH4LPBAiGI7CbxqyZx8mtROXcAptg=="], + "@aws-sdk/client-bedrock-agentcore-control": ["@aws-sdk/client-bedrock-agentcore-control@3.1143.0", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/credential-provider-node": "^3.972.84", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-SVoAtkJlv5Z/mdQy2TrnO5+ZT82sJzWaQ6Cz+MFDXfytXtd7mE+B2JyLGw7ih+wCnd2uX6m+XZ0/GWYgrVvD5w=="], "@aws-sdk/client-cloudcontrol": ["@aws-sdk/client-cloudcontrol@3.1121.0", "", { "dependencies": { "@aws-sdk/core": "^3.977.9", "@aws-sdk/credential-provider-node": "^3.972.81", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-kpR+c528XFWFT04APYPKrhSCyzdEJPgxryR0wWs2dfIj7Ovqwak+1zLwFOS8zpNqDPEx8xn7j3dqA/HTCo+qLw=="], @@ -1675,6 +1675,20 @@ "@aws-sdk/client-bedrock-agent/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.81", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-ini": "^3.973.15", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Rml+WitoFvXmv6JZ18U/xGdGDGGvB/mOin0ya0lTnTrdC0Z1lrVxTYh7iNklZBcvcRMrs4DoEf6xy1KWyrLQQw=="], + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/core": ["@aws-sdk/core@3.978.1", "", { "dependencies": { "@aws-sdk/types": "^3.974.6", "@aws-sdk/xml-builder": "^3.972.41", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.35.0", "@smithy/signature-v4": "^5.7.3", "@smithy/types": "^4.19.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-LbY9aGsEiznDWmUc30Nwv3aIX/+dbwTx8KfS0yOC3NPYMO+O91e6jkT1azf34FwjOndq8/Q+RcVVZz5xnerwdg=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.84", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.72", "@aws-sdk/credential-provider-http": "^3.972.74", "@aws-sdk/credential-provider-ini": "^3.973.17", "@aws-sdk/credential-provider-process": "^3.972.72", "@aws-sdk/credential-provider-sso": "^3.973.16", "@aws-sdk/credential-provider-web-identity": "^3.972.78", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-oHt854odINVwzwsh+c5x69j0ajm4DbqqqVJ+O1ECsCIZeMDAbzFpXItaqP7UZstJj/ATdTk/KFSH0LaNAgV+kA=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/types": ["@aws-sdk/types@3.974.6", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-v/clNZzZnDxGyvpHMOGpJKVXFAExJzUNAAjaWGdcx8QAcXLGwTaOkw33p5SHAi0YAioK32xB3hWwOekRVfmfKg=="], + + "@aws-sdk/client-bedrock-agentcore-control/@smithy/core": ["@smithy/core@3.35.0", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-zRMhfkByhT2snNdr1si24vJitU6Cr9ix2MikUfWmkAgp4jrNP0GcKSP5YvwQ+TlI8AZXER5QOGJn3JsVtSD9/A=="], + + "@aws-sdk/client-bedrock-agentcore-control/@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.8.0", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ycSJu3tFAQ4v04CBB0agqFMVsSQ1iG3yw+SpgxRqKfaURpQD4CZ8Wn0zPMmSnOuTpTh65Vz+EA0rMrw089wvkA=="], + + "@aws-sdk/client-bedrock-agentcore-control/@smithy/node-http-handler": ["@smithy/node-http-handler@4.12.1", "", { "dependencies": { "@smithy/core": "^3.33.3", "@smithy/types": "^4.18.0", "tslib": "^2.6.2" } }, "sha512-ThMkboGeONWXAelq9FvGsuJC4rOi+qyC4/zhUF58xYpxUg5sQKx2VXZYJmtNjr4dSuBJ1HeJXETQILCz3wOHvw=="], + + "@aws-sdk/client-bedrock-agentcore-control/@smithy/types": ["@smithy/types@4.19.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-r7jh49VJxGerfAcTQA6gXcKc+98zOp/tqRwzYjgOE+iSQsP6cEU1hq2QzbuipmP68QtYdY9wKEhiCQZIzHgZ4Q=="], + "@aws-sdk/client-cloudcontrol/@aws-sdk/core": ["@aws-sdk/core@3.977.9", "", { "dependencies": { "@aws-sdk/types": "^3.974.5", "@aws-sdk/xml-builder": "^3.972.40", "@aws/lambda-invoke-store": "^0.3.0", "@smithy/core": "^3.33.3", "@smithy/signature-v4": "^5.6.12", "@smithy/types": "^4.17.2", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-reqPFEQrZxDZpeGj4PFMepBeR5LGYHRqq/L0motTzgFkCRBA4rFdaVXDSLYyGHhxVz7sT2PDnPN9CluGSfgyJA=="], "@aws-sdk/client-cloudcontrol/@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.81", "", { "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.70", "@aws-sdk/credential-provider-http": "^3.972.72", "@aws-sdk/credential-provider-ini": "^3.973.15", "@aws-sdk/credential-provider-process": "^3.972.70", "@aws-sdk/credential-provider-sso": "^3.973.14", "@aws-sdk/credential-provider-web-identity": "^3.972.76", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/credential-provider-imds": "^4.4.16", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-Rml+WitoFvXmv6JZ18U/xGdGDGGvB/mOin0ya0lTnTrdC0Z1lrVxTYh7iNklZBcvcRMrs4DoEf6xy1KWyrLQQw=="], @@ -1905,6 +1919,20 @@ "@aws-cdk/cx-api/@aws-cdk/cloud-assembly-schema/semver": ["semver@7.8.5", "", { "bundled": true, "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/core/@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.41", "", { "dependencies": { "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-ctjVSyCMegrWfXlx6VqzSBFI6UqmQ5ZlnfMhdLIiWmhoH8UAQxSCP5N3OpG7X3k4LnS7ou74C4mt20+bfTW2aQ=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-xTKO/FWJPozTIXbozVnVGoNBhaGba8TBcx+KyUjRVeOlXE+dUc7GTR1cLvu0uTdIdmemzaFbqqCshXeZA1fZew=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.74", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-u91E/hT8f4d1xy0Jl7VG4nVKJ3lxbrZkoBTeSVoJdWBiSEUMwMS/9+e0H/aJVQV//Lt5wuzP+E69v4aRSsNTmw=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.973.17", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/credential-provider-env": "^3.972.72", "@aws-sdk/credential-provider-http": "^3.972.74", "@aws-sdk/credential-provider-login": "^3.972.79", "@aws-sdk/credential-provider-process": "^3.972.72", "@aws-sdk/credential-provider-sso": "^3.973.16", "@aws-sdk/credential-provider-web-identity": "^3.972.78", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/credential-provider-imds": "^4.5.2", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-ged4KXdBkvIC81bLvNHHuQKdKak/VXhQTR1NWYTTqW0474nlmsxy9O/vlgTIohDDWH3xpBdtVMZRyjb+DnocDA=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.72", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-rLIp2xbMjX/k9/od7APpqq1ZgXXnV0pOL1Th3ZsL8Wu0TRtBsDTVS8iPqcfRFcHakFxPvR04OSTv2ka2qOb/2A=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.973.16", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/token-providers": "3.1138.0", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-IGihaJfFZYacJJr/odqILCoK7W/mvrZ7cuK7ECn3sAu4vLC6u0V8bS7mCGbdugJ8Aum2tnvqmx0F2MRFp2rn9g=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.78", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-/y9WvNtlcPBGLR0qc1a+9J/xtYZfVczvLUOuXaVWylzttH7ewsxwHtjmiJSolNrVSDorIxHGHMU61CbonRkmwA=="], + "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.78", "", { "dependencies": { "@aws-sdk/core": "^3.978.0", "@aws-sdk/nested-clients": "^3.997.45", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-eUtswnXu0+Ii9ieRK+0L7aPFV3Z/dnW2VntJzjBP9xs8s+8p5nBNuymIXtXwZ+5r5+XJP3e32nMkuZ/r0HozEA=="], "@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.45", "", { "dependencies": { "@aws-sdk/core": "^3.978.0", "@aws-sdk/signature-v4-multi-region": "^3.996.46", "@aws-sdk/types": "^3.974.5", "@smithy/core": "^3.33.3", "@smithy/fetch-http-handler": "^5.7.2", "@smithy/node-http-handler": "^4.11.3", "@smithy/types": "^4.17.2", "tslib": "^2.6.2" } }, "sha512-mooq9Q+jLa18VoM7HouczmslZU60iiB0aKc/Ztnq/luIL1ud0z4DnYprLR/ZO1gp331S9tJctM1HZr7u6YKBXQ=="], @@ -1955,8 +1983,24 @@ "@aws-cdk/cloudformation-diff/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.79", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-L+Z85anONJd8MaiuraO4wRxATCdEejBZ3K3eymzWI5JPXa9sOS9CkIm72PBKqXKX+Z9p9NGMX5AIMXm0LEflgw=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.46", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/signature-v4-multi-region": "^3.996.47", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.46", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/signature-v4-multi-region": "^3.996.47", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1138.0", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/nested-clients": "^3.997.46", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-GpyAr0DD63YOEmYFM6Df+gJuIgC92MMTiBK4FTKfxii5MJ9ge20epR7LyroulscYlG89J+ZB2ivFDPjvfQhzdw=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.46", "", { "dependencies": { "@aws-sdk/core": "^3.978.1", "@aws-sdk/signature-v4-multi-region": "^3.996.47", "@aws-sdk/types": "^3.974.6", "@smithy/core": "^3.35.0", "@smithy/fetch-http-handler": "^5.8.0", "@smithy/node-http-handler": "^4.12.1", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-oRxtBcka/JGHGs9l9p9IVajGoTP8vTPmoAzdHGy4Qcy9P5vPnDf6nhIeM/COQNY9k/OahImTRaLkHftoXvfcmQ=="], + "@aws-sdk/signature-v4/@smithy/signature-v4/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@1.1.0", "", { "dependencies": { "@smithy/is-array-buffer": "^1.1.0", "tslib": "^2.5.0" } }, "sha512-9m6NXE0ww+ra5HKHCHig20T+FAwxBAm7DIdwc/767uGWbRcY720ybgPacQNB96JMOI7xVr/CDa3oMzKmW4a+kw=="], "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-ini/@aws-sdk/nested-clients/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.47", "", { "dependencies": { "@aws-sdk/types": "^3.974.6", "@smithy/signature-v4": "^5.7.3", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/nested-clients/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.47", "", { "dependencies": { "@aws-sdk/types": "^3.974.6", "@smithy/signature-v4": "^5.7.3", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g=="], + + "@aws-sdk/client-bedrock-agentcore-control/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-web-identity/@aws-sdk/nested-clients/@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.47", "", { "dependencies": { "@aws-sdk/types": "^3.974.6", "@smithy/signature-v4": "^5.7.3", "@smithy/types": "^4.19.0", "tslib": "^2.6.2" } }, "sha512-Zk08macMvQTHzQJCLJVkOlviVoqwYMrpXv4lmLN7b7sAbiMoOK7Go0NYdR5UeF+MW8LIbRmwrNy9u/5VvX1U5g=="], } } diff --git a/package.json b/package.json index 1eef0f470f..78e7a17d62 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@aws-sdk/client-application-signals": "^3.1092.0", "@aws-sdk/client-bedrock-agent": "^3.1092.0", "@aws-sdk/client-bedrock-agentcore": "^3.1135.0", - "@aws-sdk/client-bedrock-agentcore-control": "^3.1129.0", + "@aws-sdk/client-bedrock-agentcore-control": "^3.1143.0", "@aws-sdk/client-cloudformation": "^3.1092.0", "@aws-sdk/client-cloudwatch-logs": "^3.1092.0", "@aws-sdk/client-iam": "^3.1080.0", diff --git a/src/handlers/payment/payment.read.test.tsx b/src/handlers/payment/payment.read.test.tsx index ef4fc4b9c5..7416681296 100644 --- a/src/handlers/payment/payment.read.test.tsx +++ b/src/handlers/payment/payment.read.test.tsx @@ -88,13 +88,10 @@ test.each([ "--secrets", ...secrets, ...(clientToken ? ["--client-token", clientToken] : []), - "--endpoint-url", - "https://control.example.test", "--json", ]); expect(createControlClient).toHaveBeenCalledWith({ region: "us-west-2", - endpoint: "https://control.example.test", }); expect(send).toHaveBeenCalledTimes(1); const command = send.mock.calls[0]![0]; From 82e85a463b8e14744f073f4ff729666ed263adb6 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 30 Sep 2026 15:11:47 +0000 Subject: [PATCH 5/8] fix(ci): skip secret-backed Slack notifications for fork PRs --- .github/workflows/slack-pr-review-notification.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/slack-pr-review-notification.yml b/.github/workflows/slack-pr-review-notification.yml index 846228e155..0eb7766299 100644 --- a/.github/workflows/slack-pr-review-notification.yml +++ b/.github/workflows/slack-pr-review-notification.yml @@ -17,5 +17,7 @@ permissions: jobs: call: + # Fork PRs do not receive the AWS credentials required for notifications. + if: github.event.pull_request.head.repo.full_name == github.repository uses: aws/agentcore-devx-devtools/.github/workflows/reusable-slack-pr-review-notification.yml@626595f508220b53805c86c1b54d089420add4d3 secrets: inherit From f9c0314630a891e697e244aaae6fa14ea4351797 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 30 Sep 2026 15:12:29 +0000 Subject: [PATCH 6/8] docs(payment): regenerate credential rotation reference --- command.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/command.md b/command.md index 066999f5e4..106553f702 100644 --- a/command.md +++ b/command.md @@ -195,6 +195,7 @@ This reference was generated from `agentcore --help` for version `1.0.0-rc.4`. - [`agentcore payment connector`](#agentcore-payment-connector) - [`agentcore payment connector get`](#agentcore-payment-connector-get) - [`agentcore payment connector list`](#agentcore-payment-connector-list) + - [`agentcore payment connector rotate-credentials`](#agentcore-payment-connector-rotate-credentials) - [`agentcore payment session`](#agentcore-payment-session) - [`agentcore payment session get`](#agentcore-payment-session-get) - [`agentcore payment session list`](#agentcore-payment-session-list) @@ -2845,6 +2846,21 @@ list the connectors of a payment manager - `--next-token `: pagination token returned by a previous request - `--max-results `: maximum number of items to return +##### `agentcore payment connector rotate-credentials` + +```text +agentcore payment connector rotate-credentials [options] +``` + +rotate service-managed credentials for a Quick Create Coinbase connector + +**Options** + +- `--manager-id `: the parent payment manager ID (required) +- `--connector-id `: the payment connector ID (required) +- `--secrets `: credential kinds to rotate: API\_KEY, WALLET\_SECRET, or both (not secret values) (required) +- `--client-token `: idempotency token for this request + #### `agentcore payment session` ```text From cee925713fc3278c495382c19a97c0943db4f739 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 30 Sep 2026 18:31:21 +0000 Subject: [PATCH 7/8] docs(payment): move rotation guidance out of the README --- README.md | 22 +--------------- docs/payment-connector-credentials.md | 38 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 docs/payment-connector-credentials.md diff --git a/README.md b/README.md index 7420f328dc..21cdd56fa6 100644 --- a/README.md +++ b/README.md @@ -95,27 +95,6 @@ One-shot commands return JSON output, status, exit code, and session ID. Escape interrupts the local stream, not necessarily the remote process. Use `runtime shell` for a native interactive terminal. -### Rotate Payment Connector Credentials - -Only READY Coinbase Quick Create connectors support credential rotation. -`--secrets` selects `API_KEY`, `WALLET_SECRET`, or both; it does not accept secret -values. Rotation uses the connector's existing consent and the caller's -control-plane IAM permissions, without an application user ID. - -```bash -agentcore payment connector rotate-credentials \ - --manager-id "$MANAGER_ID" --connector-id "$CONNECTOR_ID" \ - --secrets API_KEY WALLET_SECRET -``` - -The service performs the rotation and returns its result. An optional -`--client-token` identifies retries of the same request. - -Wallet-secret rotation can interrupt wallet operations while the new credential -is installed. Selecting both credentials rotates the API key first, then the -wallet secret; this is not atomic. An error does not guarantee that credentials -are unchanged. - ## Extending the CDK app `agentcore/cdk/` has two source files. `bin/cdk.ts` reads the project once @@ -201,4 +180,5 @@ declares, not the ones you add in the stack. - [Amazon Bedrock AgentCore documentation](https://docs.aws.amazon.com/bedrock-agentcore/): service guides and API references. - [Harness project configuration](docs/harness-project-configuration.md): Harness YAML, prompts, tools, skills, and environment settings. +- [Payment connector credentials](docs/payment-connector-credentials.md): credential rotation and its scope. - [Contributing](CONTRIBUTING.md): development, builds, architecture, and testing. diff --git a/docs/payment-connector-credentials.md b/docs/payment-connector-credentials.md new file mode 100644 index 0000000000..961e1522bb --- /dev/null +++ b/docs/payment-connector-credentials.md @@ -0,0 +1,38 @@ +# Payment connector credential rotation + +[Back to README](../README.md) + +`agentcore payment connector rotate-credentials` replaces service-managed credentials +for a READY Coinbase CDP connector provisioned through Quick Create (`QUICK_CREATE`). +It uses the caller's control-plane IAM permissions and does not require an application user ID. +For `MANUAL` connectors, rotate credentials with the payment provider directly, then update +the payment credential provider. + +## Select Credentials + +`--secrets` accepts credential kinds, not secret values: + +- `API_KEY`: rotate for routine maintenance or suspected compromise. +- `WALLET_SECRET`: rotate only if lost or compromised. Coinbase CDP allows one wallet secret per + project, so replacement happens in place and signing can be briefly interrupted. + +```bash +agentcore payment connector rotate-credentials \ + --manager-id "$MANAGER_ID" --connector-id "$CONNECTOR_ID" \ + --secrets API_KEY +``` + +Select both with `--secrets API_KEY WALLET_SECRET` when needed. An optional `--client-token` +identifies retries of the same request. + +## Behavior And Scope + +The [AWS SDK reference](https://docs.aws.amazon.com/boto3/latest/reference/services/bedrock-agentcore-control/client/rotate_payment_connector_credentials.html) +specifies that rotation finishes before the response is returned, with only one rotation at a time +for a given connector. On success, the new credential is in effect and the connector remains +`READY`. On failure, the API returns an error and leaves the connector and its existing credential +unchanged. + +Rotation changes the credential on the connector's credential provider, so **every connector +using that provider is affected**. Replace any copies of the previous credential used outside +AgentCore. From 7a419597dd0c5272ae58a6a8678d3d18ba0894f7 Mon Sep 17 00:00:00 2001 From: Aidan Daly Date: Wed, 30 Sep 2026 18:36:19 +0000 Subject: [PATCH 8/8] docs(payment): remove the dedicated rotation guide --- README.md | 1 - docs/payment-connector-credentials.md | 38 --------------------------- 2 files changed, 39 deletions(-) delete mode 100644 docs/payment-connector-credentials.md diff --git a/README.md b/README.md index 21cdd56fa6..f3068675bb 100644 --- a/README.md +++ b/README.md @@ -180,5 +180,4 @@ declares, not the ones you add in the stack. - [Amazon Bedrock AgentCore documentation](https://docs.aws.amazon.com/bedrock-agentcore/): service guides and API references. - [Harness project configuration](docs/harness-project-configuration.md): Harness YAML, prompts, tools, skills, and environment settings. -- [Payment connector credentials](docs/payment-connector-credentials.md): credential rotation and its scope. - [Contributing](CONTRIBUTING.md): development, builds, architecture, and testing. diff --git a/docs/payment-connector-credentials.md b/docs/payment-connector-credentials.md deleted file mode 100644 index 961e1522bb..0000000000 --- a/docs/payment-connector-credentials.md +++ /dev/null @@ -1,38 +0,0 @@ -# Payment connector credential rotation - -[Back to README](../README.md) - -`agentcore payment connector rotate-credentials` replaces service-managed credentials -for a READY Coinbase CDP connector provisioned through Quick Create (`QUICK_CREATE`). -It uses the caller's control-plane IAM permissions and does not require an application user ID. -For `MANUAL` connectors, rotate credentials with the payment provider directly, then update -the payment credential provider. - -## Select Credentials - -`--secrets` accepts credential kinds, not secret values: - -- `API_KEY`: rotate for routine maintenance or suspected compromise. -- `WALLET_SECRET`: rotate only if lost or compromised. Coinbase CDP allows one wallet secret per - project, so replacement happens in place and signing can be briefly interrupted. - -```bash -agentcore payment connector rotate-credentials \ - --manager-id "$MANAGER_ID" --connector-id "$CONNECTOR_ID" \ - --secrets API_KEY -``` - -Select both with `--secrets API_KEY WALLET_SECRET` when needed. An optional `--client-token` -identifies retries of the same request. - -## Behavior And Scope - -The [AWS SDK reference](https://docs.aws.amazon.com/boto3/latest/reference/services/bedrock-agentcore-control/client/rotate_payment_connector_credentials.html) -specifies that rotation finishes before the response is returned, with only one rotation at a time -for a given connector. On success, the new credential is in effect and the connector remains -`READY`. On failure, the API returns an error and leaves the connector and its existing credential -unchanged. - -Rotation changes the credential on the connector's credential provider, so **every connector -using that provider is affected**. Replace any copies of the previous credential used outside -AgentCore.