All skills
aws avatar

/amazon-bedrock

@3b23681

Builds generative AI applications on Amazon Bedrock. Covers model invocation (Converse API, InvokeModel), RAG with Knowledge Bases, Bedrock Agents, Guardrails, and AgentCore (including the Harness managed agent loop). Applies when invoking models, setting up Knowledge Bases, creating agents, applying guardrails, deploying to AgentCore, migrating/porting/converting a Bedrock Agent (including inline agents) to an AgentCore Harness, troubleshooting Bedrock errors (ThrottlingException, AccessDeniedException), or choosing models (Claude, Llama, Nova, Titan). Also for prompt caching, quota and throttling diagnosis, cost tracking, migrating between Claude model generations (4.5 to 4.6 to 4.7), chunking strategies, API selection (Converse vs InvokeModel), guardrail capabilities, and model selection. Also covers AgentCore Payments (x402, microtransactions, Payment Manager, Connector, Instrument, Coinbase CDP, Stripe Privy, paid endpoints, agent payments). NOT for custom model training, Rekognition, or Comprehend.

Use this Skill: https://skilld.dev/gh/aws/agent-toolkit-for-aws/amazon-bedrock

This session only. Nothing lands on disk.

referencesagentcore-payments-setup-script.md

≈3.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Setup Script Template

Once you have all inputs from Step 3, generate a single Python script called setup_payments.py that executes all the following steps automatically without human intervention. Write the script, then execute it.

The script must:

  1. Store payment provider credentials in AgentCore Identity
  2. Create the IAM execution role with trust policy and permissions
  3. Wait for IAM propagation (15 seconds)
  4. Create the Payment Manager and wait for READY status
  5. Create the Payment Connector
  6. Create the Payment Instrument (wallet)
  7. Print a summary of all created resources and next steps

Template

Substitute the developer's inputs into the configuration section:

"""
AgentCore Payments Setup Script
Generated by the payments skill. Executes all non-interactive setup steps.

NAMING RULES:
- Resource names (credential provider, manager, connector): lowercase alphanumeric + hyphens only.
  NO underscores, NO dots, NO uppercase. Pattern: [a-z0-9]([a-z0-9-]*[a-z0-9])?
- The paymentManagerId (returned by create) is used for CP get/list operations.
- The paymentManagerArn (returned by create) is used for DP operations (instrument, session, process).
- create_payment_session requires userId parameter.
"""
import boto3
import json
import uuid
import time
import os

# === CONFIGURATION (from developer inputs) ===
REGION = "<REGION>"                          # e.g., "ap-southeast-2"
ACCOUNT_ID = "<ACCOUNT_ID>"                  # e.g., "123456789012"
PROVIDER = "<PROVIDER>"                      # "CoinbaseCDP" or "StripePrivy"
END_USER_EMAIL = "<END_USER_EMAIL>"          # e.g., "developer@example.com"
RESOURCE_PREFIX = "paymentspoc"              # prefix for all resource names

# Read credentials from environment variables (NOT from file directly).
# Run `source .env.payments` in your terminal before executing this script.
# Do NOT pass credentials through the agent — they must stay local.

# For Coinbase:
COINBASE_API_KEY_ID = os.environ.get("COINBASE_API_KEY_ID", "")
COINBASE_API_KEY_SECRET = os.environ.get("COINBASE_API_KEY_SECRET", "")
COINBASE_WALLET_SECRET = os.environ.get("COINBASE_WALLET_SECRET", "")
# For Stripe:
AUTH_PRIVATE_KEY = os.environ.get("AUTH_PRIVATE_KEY", "")
AUTH_ID = os.environ.get("AUTH_ID", "")
PRIVY_APP_ID = os.environ.get("PRIVY_APP_ID", "")
PRIVY_APP_SECRET = os.environ.get("PRIVY_APP_SECRET", "")

# === CLIENTS ===
iam = boto3.client("iam")
cp_client = boto3.client("bedrock-agentcore-control", region_name=REGION)
dp_client = boto3.client("bedrock-agentcore", region_name=REGION)

print("=" * 60)
print("AgentCore Payments Setup")
print("=" * 60)

# === STEP 1: Store credentials ===
print("\n[1/6] Storing payment provider credentials...")
cred_name = f"{RESOURCE_PREFIX}-creds"

def create_credential_provider_with_retry(name, vendor, config, max_retries=5):
    """Create credential provider, appending a numeric suffix if name already exists."""
    for attempt in range(max_retries):
        unique_name = name if attempt == 0 else f"{name}-{attempt}"
        try:
            if vendor == "CoinbaseCDP":
                resp = cp_client.create_payment_credential_provider(
                    name=unique_name,
                    credentialProviderVendor=vendor,
                    providerConfigurationInput={"coinbaseCdpConfiguration": config}
                )
            elif vendor == "StripePrivy":
                resp = cp_client.create_payment_credential_provider(
                    name=unique_name,
                    credentialProviderVendor=vendor,
                    providerConfigurationInput={"stripePrivyConfiguration": config}
                )
            print(f"  (Using name: {unique_name})")
            return resp
        except Exception as e:
            if "already exists" in str(e).lower() or "conflict" in str(e).lower():
                print(f"  Name '{unique_name}' already exists, trying with suffix...")
                continue
            raise
    raise Exception(f"Failed to create credential provider after {max_retries} attempts")

if PROVIDER == "CoinbaseCDP":
    cred_config = {
        "apiKeyId": COINBASE_API_KEY_ID,
        "apiKeySecret": COINBASE_API_KEY_SECRET,
        "walletSecret": COINBASE_WALLET_SECRET
    }
elif PROVIDER == "StripePrivy":
    cred_config = {
        "appId": PRIVY_APP_ID,
        "appSecret": PRIVY_APP_SECRET,
        "authorizationPrivateKey": AUTH_PRIVATE_KEY,
        "authorizationId": AUTH_ID
    }

cred_resp = create_credential_provider_with_retry(cred_name, PROVIDER, cred_config)
credential_provider_arn = cred_resp["credentialProviderArn"]
print(f"  OK Credential Provider ARN: {credential_provider_arn}")

# === STEP 2: Create IAM role ===
print("\n[2/6] Creating IAM service role...")
base_role_name = f"AgentCorePayments-{RESOURCE_PREFIX}"

def create_role_with_retry(base_name, max_retries=5):
    """Create IAM role, appending a numeric suffix if name already exists."""
    for attempt in range(max_retries):
        unique_name = base_name if attempt == 0 else f"{base_name}-{attempt}"
        try:
            iam.create_role(
                RoleName=unique_name,
                AssumeRolePolicyDocument=json.dumps({
                    "Version": "2012-10-17",
                    "Statement": [{
                        "Effect": "Allow",
                        "Principal": {"Service": "bedrock-agentcore.amazonaws.com"},
                        "Action": "sts:AssumeRole",
                        "Condition": {
                            "StringEquals": {"aws:SourceAccount": ACCOUNT_ID},
                            "ArnLike": {"aws:SourceArn": f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:payment-manager/{RESOURCE_PREFIX}-*"}
                        }
                    }]
                }),
                Description="Service role for AgentCore Payments"
            )
            print(f"  (Using role name: {unique_name})")
            return unique_name
        except iam.exceptions.EntityAlreadyExistsException:
            print(f"  Role '{unique_name}' already exists, trying with suffix...")
            continue
    raise Exception(f"Failed to create role after {max_retries} attempts")

role_name = create_role_with_retry(base_role_name)

iam.put_role_policy(
    RoleName=role_name,
    PolicyName="PaymentsResourceRetrievalPolicy",
    PolicyDocument=json.dumps({
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "WorkloadIdentity",
                "Effect": "Allow",
                "Action": [
                    "bedrock-agentcore:CreateWorkloadIdentity",
                    "bedrock-agentcore:GetWorkloadAccessToken",
                    "bedrock-agentcore:GetResourcePaymentToken"
                ],
                "Resource": [
                    f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:token-vault/default",
                    f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:token-vault/default/paymentcredentialprovider/*",
                    f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:workload-identity-directory/default",
                    f"arn:aws:bedrock-agentcore:{REGION}:{ACCOUNT_ID}:workload-identity-directory/default/workload-identity/*"
                ]
            },
            {
                "Sid": "SecretsAccess",
                "Effect": "Allow",
                "Action": "secretsmanager:GetSecretValue",
                "Resource": f"arn:aws:secretsmanager:{REGION}:{ACCOUNT_ID}:secret:bedrock-agentcore-identity*"
            }
        ]
    })
)
role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/{role_name}"
print(f"  OK Role ARN: {role_arn}")
print("  Waiting 15s for IAM propagation...")
time.sleep(15)

# === STEP 3: Create Payment Manager ===
print("\n[3/6] Creating Payment Manager...")
mgr_resp = cp_client.create_payment_manager(
    name=RESOURCE_PREFIX,
    description="Payment manager created by AgentCore Payments skill",
    authorizerType="AWS_IAM",
    roleArn=role_arn,
    clientToken=str(uuid.uuid4())
)
payment_manager_arn = mgr_resp["paymentManagerArn"]
manager_id = mgr_resp["paymentManagerId"]
print(f"  OK Payment Manager ARN: {payment_manager_arn}")

# Wait for READY
for i in range(12):
    status_resp = cp_client.get_payment_manager(paymentManagerId=manager_id)
    if status_resp["status"] == "READY":
        break
    time.sleep(5)
if status_resp["status"] != "READY":
    raise Exception(
        f"Payment Manager did not reach READY status after 60s "
        f"(current: {status_resp['status']}). Check CloudTrail for errors."
    )
print(f"  OK Status: {status_resp['status']}")

# === STEP 4: Create Payment Connector ===
print("\n[4/6] Creating Payment Connector...")
connector_config_key = "coinbaseCDP" if PROVIDER == "CoinbaseCDP" else "stripePrivy"
conn_resp = cp_client.create_payment_connector(
    paymentManagerId=manager_id,
    name=f"{RESOURCE_PREFIX}connector",
    description=f"{PROVIDER} connector",
    type=PROVIDER,
    credentialProviderConfigurations=[{
        connector_config_key: {"credentialProviderArn": credential_provider_arn}
    }],
    clientToken=str(uuid.uuid4())
)
connector_id = conn_resp["paymentConnectorId"]
print(f"  OK Connector ID: {connector_id}")

# === STEP 5: Create Payment Instrument ===
print("\n[5/6] Creating Payment Instrument (wallet)...")
user_id = f"{RESOURCE_PREFIX}-user"
instr_resp = dp_client.create_payment_instrument(
    paymentManagerArn=payment_manager_arn,
    paymentConnectorId=connector_id,
    userId=user_id,
    paymentInstrumentType="EMBEDDED_CRYPTO_WALLET",
    paymentInstrumentDetails={
        "embeddedCryptoWallet": {
            "network": "ETHEREUM",
            "linkedAccounts": [
                {"email": {"emailAddress": END_USER_EMAIL}}
            ]
        }
    },
    clientToken=str(uuid.uuid4())
)
instrument_data = instr_resp.get("paymentInstrument", instr_resp)
payment_instrument_id = instrument_data["paymentInstrumentId"]
wallet_details = instrument_data.get("paymentInstrumentDetails", {}).get("embeddedCryptoWallet", {})
wallet_address = wallet_details.get("walletAddress", "pending")
redirect_url = wallet_details.get("redirectUrl", None)
print(f"  OK Instrument ID: {payment_instrument_id}")
print(f"  OK Wallet Address: {wallet_address}")

# === STEP 6: Create Payment Session ===
print("\n[6/6] Creating Payment Session...")
session_resp = dp_client.create_payment_session(
    paymentManagerArn=payment_manager_arn,
    userId=user_id,
    expiryTimeInMinutes=60
)
payment_session_id = session_resp["paymentSession"]["paymentSessionId"]
print(f"  OK Session ID: {payment_session_id}")

# === SUMMARY ===
print("\n" + "=" * 60)
print("SETUP COMPLETE")
print("=" * 60)
print(f"""
Resources created:
  Payment Manager ARN:  {payment_manager_arn}
  Connector ID:         {connector_id}
  Instrument ID:        {payment_instrument_id}
  Wallet Address:       {wallet_address}
  Session ID:           {payment_session_id}
  User ID:              {user_id}
  Region:               {REGION}

Environment variables for your agent:
  export PAYMENT_MANAGER_ARN="{payment_manager_arn}"
  export PAYMENT_INSTRUMENT_ID="{payment_instrument_id}"
  export PAYMENT_SESSION_ID="{payment_session_id}"
  export PAYMENT_USER_ID="{user_id}"
  export AWS_REGION="{REGION}"
""")

print("\nMANUAL STEPS REQUIRED:\n")

# Step 1: Delegation — provider-specific
if PROVIDER == "CoinbaseCDP":
    print(f"""1. DELEGATION — Grant the agent permission to spend from the wallet:
   Visit: {redirect_url}
   Log in with: {END_USER_EMAIL}
   Grant permissions to the wallet address: {wallet_address}
""")
elif PROVIDER == "StripePrivy":
    print(f"""1. DELEGATION — Enable delegation on the embedded wallet:
   a. Set up a frontend using the Privy frontend SDK:
      https://github.com/privy-io/aws-agentcore-sdk
   b. Log in with the end user email: {END_USER_EMAIL}
   c. Approve delegation for the wallet address: {wallet_address}
""")

# Step 2: Funding — same for both providers
print(f"""2. FUNDING — Send testnet USDC to the wallet:
   Go to: https://faucet.circle.com/
   Select: Base Sepolia
   Paste wallet address: {wallet_address}
""")

After executing the script

  • Tell the developer to run source .env.payments before executing the script
  • Print the summary to the developer
  • Tell them to complete the two manual steps (delegation + funding) for the provider they chose
  • Do NOT reference the other provider's flow — only show steps for the provider in use
  • Wait for them to confirm before proceeding to Step 5 (wiring)

Source: SKILL.md on GitHub

1 warning2d3 checks · Risk SAFE
  • Gen Agent Trust Hub2d

    This skill provides a comprehensive and secure framework for building generative AI applications on Amazon Bedrock. It incorporates industry-standard security practices, including IAM least-privilege guidance, SSRF protections, and robust encryption recommendations for sensitive data.

  • Socket2d

    1 alert: gptSecurity

  • Snyk2d

    Risk: LOW · No issues

Signed by skilld at 3b23681. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 3 days ago
metadata
{
  "version": "6"
}

README badge

README badge for aws/agent-toolkit-for-aws/amazon-bedrock