Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,10 @@ Policy engines apply Cedar-based pre/post-call policies to agent invocations —
Pay-per-call agent transactions via the [x402 protocol](https://www.x402.org/). When a tool call returns
`402 Payment Required`, the payments system signs and submits payment then retries automatically.

| Command | Description |
| ----------------------- | ---------------------------------------------------------------------------- |
| `add payment-manager` | Add a payment manager (orchestrates payment sessions for the agent) |
| `add payment-connector` | Add a payment connector with provider credentials (CoinbaseCDP, StripePrivy) |
| Command | Description |
| ----------------------- | ------------------------------------------------------------------------- |
| `add payment-manager` | Add a payment manager (orchestrates payment sessions for the agent) |
| `add payment-connector` | Add a Quick Create or manual payment connector (CoinbaseCDP, StripePrivy) |

> See [Payments](docs/payments.md) for the full setup including instrument creation and tool allowlists.

Expand Down
19 changes: 10 additions & 9 deletions docs/PERMISSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,15 +426,16 @@ Required only when the project defines payment managers and connectors (the `pay
CLI calls the Payment control-plane and data-plane APIs directly with the developer's credentials; both are signed under
the `bedrock-agentcore` service.

| Action | CLI Commands | Purpose |
| --------------------------------------------------- | ------------ | -------------------------------------------------------------------- |
| `bedrock-agentcore:GetPaymentCredentialProvider` | `deploy` | Check if a payment credential provider already exists |
| `bedrock-agentcore:CreatePaymentCredentialProvider` | `deploy` | Create a payment credential provider from connector secrets |
| `bedrock-agentcore:UpdatePaymentCredentialProvider` | `deploy` | Update a payment credential provider with new secret values |
| `bedrock-agentcore:DeletePaymentCredentialProvider` | `deploy` | Remove a payment credential provider when a connector is removed |
| `bedrock-agentcore:GetPaymentManager` | `status` | Look up payment manager status |
| `bedrock-agentcore:ListPaymentSessions` | `invoke` | Find an existing active payment session before creating a new one |
| `bedrock-agentcore:CreatePaymentSession` | `invoke` | Create a payment session with a default budget for `invoke` auto-pay |
| Action | CLI Commands | Purpose |
| --------------------------------------------------- | ------------------ | -------------------------------------------------------------------- |
| `bedrock-agentcore:GetPaymentCredentialProvider` | `deploy` | Check if a payment credential provider already exists |
| `bedrock-agentcore:CreatePaymentCredentialProvider` | `deploy` | Create a payment credential provider from connector secrets |
| `bedrock-agentcore:UpdatePaymentCredentialProvider` | `deploy` | Update a payment credential provider with new secret values |
| `bedrock-agentcore:DeletePaymentCredentialProvider` | `deploy` | Remove a payment credential provider when a connector is removed |
| `bedrock-agentcore:GetPaymentManager` | `status` | Look up payment manager status |
| `bedrock-agentcore:GetPaymentConnector` | `deploy`, `status` | Retrieve connector status and a pending authorization URL |
| `bedrock-agentcore:ListPaymentSessions` | `invoke` | Find an existing active payment session before creating a new one |
| `bedrock-agentcore:CreatePaymentSession` | `invoke` | Create a payment session with a default budget for `invoke` auto-pay |

Creating or updating a payment credential provider also writes the connector secrets into a service-managed Secrets
Manager secret (named `bedrock-agentcore-identity!default/payment/*`). Unlike API key and OAuth2 providers, the Payment
Expand Down
33 changes: 20 additions & 13 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,12 @@ agentcore add payment-manager \
Add a payment connector to an existing payment manager. See [Payments](payments.md) for credential details.

```bash
# Quick Create (recommended)
agentcore add payment-connector \
--manager MyManager \
--name MyCDPConnector \
--provision-mode QUICK_CREATE

# CoinbaseCDP provider
agentcore add payment-connector \
--manager MyManager \
Expand All @@ -541,19 +547,20 @@ agentcore add payment-connector \
--authorization-id your-auth-id
```

| Flag | Description |
| ----------------------------------- | ------------------------------------------ |
| `--manager <name>` | Parent payment manager (required) |
| `--name <name>` | Connector name (required) |
| `--provider <provider>` | `CoinbaseCDP` (default) or `StripePrivy` |
| `--api-key-id <id>` | Coinbase CDP API Key ID |
| `--api-key-secret <secret>` | Coinbase CDP API Key Secret |
| `--wallet-secret <secret>` | Coinbase CDP Wallet Secret |
| `--app-id <id>` | Privy App ID (StripePrivy) |
| `--app-secret <secret>` | Privy App Secret (StripePrivy) |
| `--authorization-private-key <key>` | ECDSA P-256 private key (StripePrivy) |
| `--authorization-id <id>` | Authorization key identifier (StripePrivy) |
| `--json` | JSON output |
| Flag | Description |
| ----------------------------------- | ------------------------------------------------------ |
| `--manager <name>` | Parent payment manager (required) |
| `--name <name>` | Connector name (required) |
| `--provision-mode <mode>` | `QUICK_CREATE` or `MANUAL` (default) |
| `--provider <provider>` | `CoinbaseCDP` or `StripePrivy` (manual mode only) |
| `--api-key-id <id>` | Coinbase CDP API Key ID (manual mode) |
| `--api-key-secret <secret>` | Coinbase CDP API Key Secret (manual mode) |
| `--wallet-secret <secret>` | Coinbase CDP Wallet Secret (manual mode) |
| `--app-id <id>` | Privy App ID (StripePrivy manual mode) |
| `--app-secret <secret>` | Privy App Secret (StripePrivy manual mode) |
| `--authorization-private-key <key>` | ECDSA P-256 private key (StripePrivy manual mode) |
| `--authorization-id <id>` | Authorization key identifier (StripePrivy manual mode) |
| `--json` | JSON output |

### add credential

Expand Down
22 changes: 14 additions & 8 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,11 @@ wallet credentials. See [Payments](payments.md) for the full usage guide.
{
"name": "MyCDPConnector",
"provider": "CoinbaseCDP",
"provisionMode": "QUICK_CREATE"
},
{
"name": "MyManualConnector",
"provider": "CoinbaseCDP",
"credentialName": "my-cdp-creds"
}
]
Expand Down Expand Up @@ -572,17 +577,18 @@ wallet credentials. See [Payments](payments.md) for the full usage guide.

### Payment Connector

| Field | Required | Description |
| ---------------- | -------- | -------------------------------------------------- |
| `name` | Yes | Connector name (alphanumeric + underscore, max 48) |
| `provider` | No | `"CoinbaseCDP"` (default) or `"StripePrivy"` |
| `credentialName` | Yes | Name of the credential (maps to `.env.local` vars) |
| Field | Required | Description |
| ---------------- | -------- | ----------------------------------------------------------------- |
| `name` | Yes | Connector name (alphanumeric + underscore, max 48) |
| `provider` | Yes | `"CoinbaseCDP"` for Quick Create; either provider for manual mode |
| `provisionMode` | Cond. | `"QUICK_CREATE"` for Quick Create; omit or use `"MANUAL"` |
| `credentialName` | Cond. | Required for manual mode; forbidden for Quick Create |

### Payment Credential Provider

Payment connectors use a `PaymentCredentialProvider` credential type, distinct from `ApiKeyCredentialProvider` and
`OAuthCredentialProvider`. The credential is automatically created during `agentcore deploy` from values in
`.env.local`. You do not need to add it to the `credentials` array manually.
Manual payment connectors use a `PaymentCredentialProvider` credential type, distinct from `ApiKeyCredentialProvider`
and `OAuthCredentialProvider`. The credential is automatically created during `agentcore deploy` from values in
`.env.local`. Quick Create provisions its provider through the service and does not add a local credential entry.

---

Expand Down
38 changes: 28 additions & 10 deletions docs/payments.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@ cd MyProject
# 2. Add a payment manager
agentcore add payment-manager --name MyManager

# 3. Add a payment connector with CoinbaseCDP credentials
# 3. Add a Coinbase connector with Quick Create
agentcore add payment-connector \
--manager MyManager \
--name MyCDPConnector \
--provider CoinbaseCDP \
--api-key-id your-api-key-id \
--api-key-secret your-api-key-secret \
--wallet-secret your-wallet-secret
--provision-mode QUICK_CREATE

# 4. Deploy (creates payment infrastructure on AWS)
# 4. Deploy, then open the authorization URL printed by the CLI
agentcore deploy -y

# 5. Create + fund an instrument out-of-band (SDK), then invoke with auto-session
Expand Down Expand Up @@ -126,8 +123,28 @@ For details on IAM role separation (ManagementRole vs ProcessPaymentRole), see
A payment connector links a credential provider (wallet credentials) to a payment manager. Each manager needs at least
one connector before it can process payments.

### Quick Create with Coinbase (Recommended)

Quick Create provisions the Coinbase credential provider through AWS after deployment. It does not collect credentials,
add a local credential entry, or write payment variables to `.env.local`.

```bash
agentcore add payment-connector \
--manager MyManager \
--name MyCDPConnector \
--provision-mode QUICK_CREATE

agentcore deploy -y
```

Deploy prints the live authorization URL. Open it to complete consent. The deployment succeeds while the connector is
`PENDING_AUTHENTICATION`; use `agentcore status --type payment` to retrieve the current status and URL. Once consent
completes, status becomes `READY` and the generated credential provider ARN appears in status output.

### CoinbaseCDP Provider

Manual mode remains available when you already manage Coinbase CDP credentials.

```bash
agentcore add payment-connector \
--manager MyManager \
Expand Down Expand Up @@ -174,8 +191,8 @@ agentcore add payment-connector \

### Credential Storage

Connector credentials are stored in `agentcore/.env.local` and never committed to source control. The env var naming
convention is:
Manual connector credentials are stored in `agentcore/.env.local` and never committed to source control. Quick Create
does not use local payment credentials. The manual env var naming convention is:

**CoinbaseCDP** (3 variables):

Expand Down Expand Up @@ -462,11 +479,12 @@ agentcore remove payment-manager --name MyManager -y
```

Removing a payment manager cascades: it deletes all associated connectors and credential providers from the local
configuration.
configuration. The CLI never imperatively deletes a provider generated by Quick Create.

## Validation

`agentcore validate` checks payment configuration for common issues:
`agentcore validate` checks payment configuration for common issues. Credential and `.env.local` checks apply only to
manual connectors:

- Credential cross-references: verifies each connector's `credentialName` maps to a valid credential entry
- `.env.local` existence: confirms the secrets file exists when payment connectors are configured
Expand Down
1 change: 1 addition & 0 deletions docs/policies/iam-policy-user.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"bedrock-agentcore:UpdatePaymentCredentialProvider",
"bedrock-agentcore:DeletePaymentCredentialProvider",
"bedrock-agentcore:GetPaymentManager",
"bedrock-agentcore:GetPaymentConnector",
"bedrock-agentcore:ListPaymentSessions",
"bedrock-agentcore:CreatePaymentSession"
],
Expand Down
119 changes: 119 additions & 0 deletions integ-tests/add-remove-payment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,125 @@ describe('integration: add and remove payment managers and connectors', () => {
});
});

describe('Quick Create connector lifecycle', () => {
const managerName = `IntegQuickMgr${Date.now().toString().slice(-6)}`;
const connectorName = `IntegQuick${Date.now().toString().slice(-6)}`;
let envBefore = '';

beforeAll(async () => {
await runCLI(['add', 'payment-manager', '--name', managerName], project.projectPath);
envBefore = await readFile(join(project.projectPath, 'agentcore', '.env.local'), 'utf-8').catch(() => '');
});

it('adds Quick Create without provider or credential flags', async () => {
const result = await runCLI(
[
'add',
'payment-connector',
'--manager',
managerName,
'--name',
connectorName,
'--provision-mode',
'QUICK_CREATE',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout)).toEqual(
expect.objectContaining({
success: true,
managerName,
connectorName,
})
);

const config = await readProjectConfig(project.projectPath);
const manager = config.payments?.find((p: Record<string, unknown>) => p.name === managerName);
expect(manager?.connectors).toEqual([
{
name: connectorName,
provider: 'CoinbaseCDP',
provisionMode: 'QUICK_CREATE',
},
]);
expect(
config.credentials?.some((c: Record<string, unknown>) => c.authorizerType === 'PaymentCredentialProvider')
).toBe(false);
});

it('does not write payment secrets to .env.local', async () => {
const envAfter = await readFile(join(project.projectPath, 'agentcore', '.env.local'), 'utf-8').catch(() => '');
expect(envAfter).toBe(envBefore);
});

it('rejects credential flags with Quick Create', async () => {
const result = await runCLI(
[
'add',
'payment-connector',
'--manager',
managerName,
'--name',
`${connectorName}Secret`,
'--provision-mode',
'QUICK_CREATE',
'--api-key-id',
'must-not-be-used',
'--json',
],
project.projectPath
);

expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout).error).toContain('Credential options cannot be used with QUICK_CREATE');
});

it('rejects StripePrivy with Quick Create', async () => {
const result = await runCLI(
[
'add',
'payment-connector',
'--manager',
managerName,
'--name',
`${connectorName}Stripe`,
'--provision-mode',
'QUICK_CREATE',
'--provider',
'StripePrivy',
'--json',
],
project.projectPath
);

expect(result.exitCode).toBe(1);
expect(JSON.parse(result.stdout).error).toContain('QUICK_CREATE only supports the CoinbaseCDP provider');
});

it('validates a Quick Create connector without local credentials', async () => {
const result = await runCLI(['validate'], project.projectPath);
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
});

it('removes Quick Create without credential cleanup', async () => {
const result = await runCLI(
['remove', 'payment-connector', '--manager', managerName, '--name', connectorName, '--yes', '--json'],
project.projectPath
);
expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);

const envAfter = await readFile(join(project.projectPath, 'agentcore', '.env.local'), 'utf-8').catch(() => '');
expect(envAfter).toBe(envBefore);
});

afterAll(async () => {
await runCLI(['remove', 'payment-manager', '--name', managerName, '--yes'], project.projectPath);
});
});

describe('StripePrivy connector lifecycle', () => {
const managerName = `IntegSpMgr${Date.now().toString().slice(-6)}`;
const connectorName = `IntegSpConn${Date.now().toString().slice(-6)}`;
Expand Down
Loading
Loading