Reference
AWS
SigV4 credentials and the boto3 bridge.
AWS managed secrets carry extra structure because Alter computes the full AWS Signature Version 4 (SigV4) signature per outgoing request. One stored AWS access key works against every AWS service — S3, Lambda, DynamoDB, Bedrock, CloudWatch — without any per-service configuration.
| Property | Value |
|---|---|
| Provider ID | aws |
| Credential type | SigV4 |
| Required credentials | Access Key ID + Secret Access Key |
| Region / service | Auto-detected from the request URL |
Storing the credential
Section titled “Storing the credential”- In the AWS IAM Console, create or pick a user with least-privilege permissions and generate an access key.
- In the developer portal: Managed Secrets → Add Provider → AWS.
- Paste Access Key ID and Secret Access Key. No region or service configuration is needed.
- Save. A
grant_idis returned.
Never use root account access keys. Always scope IAM permissions to the routes the application needs.
Calling AWS — app.request() (Python and TypeScript)
Section titled “Calling AWS — app.request() (Python and TypeScript)”The default path. Pass the standard AWS hostname; Alter parses region and service from the URL and signs the request.
import os
from alter_sdk import App, HttpMethod
async with App(api_key=os.environ["ALTER_API_KEY"]) as app: # S3 r = await app.request( HttpMethod.GET, "https://s3.us-east-1.amazonaws.com/my-bucket/my-key", grant_id=os.environ["AWS_GRANT_ID"], )
# Bedrock — same credential, different service and region r = await app.request( HttpMethod.POST, "https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-sonnet-4-6/invoke", grant_id=os.environ["AWS_GRANT_ID"], json={"prompt": "Hello"}, )
# Lambda r = await app.request( HttpMethod.POST, "https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/my-func/invocations", grant_id=os.environ["AWS_GRANT_ID"], json={"key": "value"}, )import { App, HttpMethod } from "@alter-ai/alter-sdk";
const app = new App({ apiKey: process.env.ALTER_API_KEY! });const grantId = process.env.AWS_GRANT_ID!;try { // S3 const s3 = await app.request( HttpMethod.GET, "https://s3.us-east-1.amazonaws.com/my-bucket/my-key", { grantId }, );
// Bedrock const bedrock = await app.request( HttpMethod.POST, "https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-sonnet-4-6/invoke", { grantId, json: { prompt: "Hello" } }, );} finally { await app.close();}No AWS SDK dependency. SigV4 is computed by the Alter SDK using standard cryptographic libraries.
Calling AWS — boto3_client() (Python only)
Section titled “Calling AWS — boto3_client() (Python only)”For applications that prefer the native boto3 API (response parsing, pagination, botocore.exceptions.ClientError):
pip install 'alter-sdk[aws]'import asyncioimport os
from alter_sdk import App
async def main(): async with App(api_key=os.environ["ALTER_API_KEY"]) as app: s3 = await app.boto3_client( "s3", grant_id=os.environ["AWS_GRANT_ID"], region_name="us-east-1", reason="Listing objects for data pipeline", )
# boto3 methods are synchronous — run in a thread from async code resp = await asyncio.to_thread( s3.list_objects_v2, Bucket="my-bucket", MaxKeys=10, ) for obj in resp.get("Contents", []): print(obj["Key"], obj["Size"])
# Same credential, different service dynamo = await app.boto3_client( "dynamodb", grant_id=os.environ["AWS_GRANT_ID"], region_name="us-east-1", ) await asyncio.to_thread( dynamo.put_item, TableName="MyTable", Item={"pk": {"S": "k1"}}, )
asyncio.run(main())Every boto3 call routes through Alter — credential retrieval, SigV4 signing, policy enforcement, audit logging all happen on every call.
boto3_client() parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
service_name | str | — | AWS service (s3, dynamodb, bedrock-runtime, …). |
grant_id | str | — | The AWS grant. |
region_name | str | None | None — boto3 default (us-east-1) | AWS region. |
timeout | float | None | None — client timeout + 5s buffer | Total wall-clock timeout per call (seconds), covering token retrieval and the HTTP request. |
reason | str | None | None | Audit reason applied to every call from this client. |
context | dict[str, str] | None | None | Per-client audit context. |
Error handling matches native boto3 (botocore.exceptions.ClientError for AWS errors like NoSuchBucket, AccessDenied; AlterSDKError for Alter-side issues).
boto3_client() buffers responses in memory. For large objects, use
provider-supported range/chunk requests and keep each response bounded; neither
Python helper exposes a one-call multi-GB streaming API.
Supported URL patterns
Section titled “Supported URL patterns”Alter auto-detects region and service from these AWS hostname formats:
| Pattern | Example | Detected |
|---|---|---|
| Standard | s3.us-east-1.amazonaws.com | service s3, region us-east-1 |
| Hyphenated service | bedrock-runtime.us-west-2.amazonaws.com | service bedrock-runtime, region us-west-2 |
| S3 virtual-hosted | my-bucket.s3.us-west-2.amazonaws.com | service s3, region us-west-2 |
| PrivateLink (regional) | vpce-xxx.monitoring.us-east-2.vpce.amazonaws.com | service monitoring, region us-east-2 |
| PrivateLink (zonal) | vpce-xxx-us-east-2c.monitoring.us-east-2.vpce.amazonaws.com | service monitoring, region us-east-2 |
| GovCloud | s3.us-gov-west-1.amazonaws.com | service s3, region us-gov-west-1 |
For non-AWS custom domains (LocalStack, custom proxies), region and service cannot be auto-detected. Contact support to wire explicit configuration.
Errors and signing diagnostics
Section titled “Errors and signing diagnostics”The request hostname is the source of truth for standard AWS endpoints. Its detected region and service take precedence over fallback metadata, so one stored access key can call multiple regions and services. Do not create a separate Alter credential per region solely for signing.
BackendErrorbefore the provider call means the resolved grant did not carry complete signing material. Store the credential again with both the access key ID and secret access key.ProviderAPIErrorwith an AWSSignatureDoesNotMatchresponse means the URL was signed for a different region or signing service than AWS expected. Use one of the supported hostname forms above and confirm the URL names the intended region and service.- A custom hostname with no detectable region or service cannot be signed automatically. The SDK fails before sending the request rather than guessing.
- Python
boto3_client()preserves native AWS failures asbotocore.exceptions.ClientError; Alter-side setup and grant failures remainAlterSDKErrorsubclasses.
Rotation
Section titled “Rotation”When the AWS access key rotates: regenerate in IAM, then update the stored value in the portal under Managed Secrets → AWS → Update credential. Every existing grant_id keeps working with the new key.
What’s next
Section titled “What’s next”General managed-secret flow.
Managed secret providersOther catalog entries.
Python SDKboto3_client() and request() reference.
Policy-cataloged operations
Section titled “Policy-cataloged operations”Alter policy rules can target these attested operations and families for operation-level and parameter-aware controls.
| Operation ID | Families | Method | Provider path |
|---|---|---|---|
sns/Publish | admin, delete, read, send, write | POST | / |
s3/DeleteObject | admin, delete | DELETE | /{Bucket}/{Key} |
s3/PutObject | admin, write | PUT | /{Bucket}/{Key} |
lambda/Invoke | write | POST | /2015-03-31/functions/{FunctionName}/invocations |
s3/CreateBucket | write | PUT | /{Bucket} |
lambda/ListFunctions | read | GET | /2015-03-31/functions |
s3/GetObject | read | GET | /{Bucket}/{Key} |
s3/HeadObject | read | HEAD | /{Bucket}/{Key} |
s3/ListBuckets | read | GET | / |
s3/ListObjectsV2 | read | GET | /{Bucket} |