# Use AWS

```yaml
capability_id: aws.use
display_name: Use general AWS API relay
ui_capability_key: use_aws_relay
scope: aws:use
endpoint:
  method: POST
  path: /aws/request
operation: aws.request
billable: true
environment: none
```

## Purpose and authorization

The `aws:use` scope authorizes an authenticated application to use Gateman's
native AWS HTTP relay for inspecting, configuring, auditing, and managing AWS
resources without disclosing AWS credentials.

Gateman authenticates the application, checks `aws:use`, retrieves the
application's protected AWS relay credentials, signs the supplied native
request with AWS Signature Version 4, executes it against the selected AWS
endpoint, and returns the bounded AWS response. AWS IAM remains authoritative
for the actual AWS action and resource authorization.

This is not an IAM policy engine, configuration-management platform,
infrastructure-as-code system, AWS SDK abstraction, or replacement for
AWS-native permission models. It is not read-only: authorized AWS mutations
can be performed through the relay. The application must use [Contract
v1](https://docs.getgateman.com/contract-v1/) and hold `aws:use`.

## Implementation contract

```http
POST /aws/request
Content-Type: application/json
X-GM-App: app_...
X-GM-Ts: 1710000000
X-GM-Sig: <Contract-v1-signature>
X-GM-Idempotency-Key: optional-gateman-key
```

`X-GM-Sig` is the Contract v1 HMAC-SHA256 or Ed25519 signature for the exact
outer request. It is not the AWS SigV4 signature. Gateman creates the AWS
signature after validating the nested request. The optional
`X-GM-Idempotency-Key` participates in Contract v1 signing, but this route has
no Gateman replay ledger and does not deduplicate AWS requests.

The request body is a JSON object containing a native AWS HTTP request. The
native request body is represented by the `body` string; it is not a nested
JSON object interpreted by Gateman.

The Official PHP, Node.js, Python, and Go clients all support this generic
authenticated request contract and can call `/aws/request`. No AWS-specific
Gateman client helper is required; agents must not invent provider-specific
helper methods.

## Request schema

| Field | Required | Contract |
| --- | --- | --- |
| `endpoint` | Yes | AWS HTTPS endpoint; maximum 512 bytes. |
| `service` | Yes | SigV4 service token, 1–63 letters, digits, or hyphens. |
| `region` | Yes | SigV4 region token, 1–63 letters, digits, or hyphens. |
| `method` | No | Defaults to `POST`; `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, or `HEAD`. |
| `path` | Yes | Begins with `/`; maximum 2,048 bytes. |
| `query` | No | JSON object; defaults to `{}`. Values are scalar or arrays. |
| `headers` | No | JSON object; defaults to `{}`. Names and values are strings. |
| `body` | No | String; defaults to `""`. |
| `body_encoding` | No | `utf8` or strict `base64`; defaults to `utf8`. |

Unknown top-level fields are silently ignored by the current validator. Send
only documented fields. The route does not expose an AWS SDK operation-name
interface.

The path must begin with `/`, must not contain a query string, controls,
spaces, `#`, `<`, `>`, quotes, `..`, or `//`, and must be no larger than 2,048
bytes. Put query parameters in `query`, not in `path`.

`query` is encoded with PHP RFC 3986 query encoding. The encoded query is
limited to 2,048 bytes independently of the path. It is a structured map,
not a raw query string. Duplicate query keys cannot be represented faithfully;
array values use PHP query encoding, including indexed bracket notation.

`headers` is a string-to-string map. Duplicate header fields cannot be
represented. Values and names containing carriage returns or line feeds are
rejected. `proxy-*` headers and these protected headers are rejected:
`Authorization`, `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`,
`Proxy-Authorization`, `Proxy-Authenticate`, `Upgrade`, `Cookie`,
`X-Amz-Date`, `X-Amz-Security-Token`, `X-Amz-Content-Sha256`,
`X-Amz-Credential`, `X-Amz-Algorithm`, and `X-Amz-SignedHeaders`.

Gateman creates AWS authentication and signing headers. The caller must
provide other native headers such as `Content-Type` and `X-Amz-Target` when
required. Caller-provided header name/value data is limited to 16 KiB.

For AWS JSON or JSON-RPC APIs, serialize the provider JSON document into the
`body` string:

```json
{
  "body": "{\"Name\":\"example-rule\",\"State\":\"ENABLED\"}",
  "body_encoding": "utf8"
}
```

For AWS Query APIs, construct the form-encoded body, such as
`Action=ListRoles&Version=2010-05-08`. For supported binary content, use strict
base64. The decoded body is limited to 1 MiB. Gateman signs and forwards the
decoded bytes without parsing or reserializing them.

## AWS endpoint selection and SigV4

The caller supplies `endpoint`, `service`, and `region`. Gateman uses the
installed AWS SDK SigV4 implementation with the protected application
credentials. It does not select an endpoint from an AWS service catalogue and
does not implement every AWS endpoint-resolution rule.

The endpoint must use HTTPS and port 443, contain no URL credentials, query,
or fragment, contain no IP literal, use a valid DNS hostname, and use one of
these AWS-owned suffixes: `amazonaws.com`, `amazonaws.com.cn`, `c2s.ic.gov`,
`sc2s.sgov.gov`, or `cloud.adc-e.uk`.

The first hostname label must match the lowercased signing service, except for
these aliases:

| Signing service | Accepted first hostname label |
| --- | --- |
| `ses` or `sesv2` | `ses` or `email` |
| `cloudwatch` | `cloudwatch` or `monitoring` |

CloudWatch commonly uses `monitoring.<region>.amazonaws.com`, and SES uses
`email.<region>.amazonaws.com`. Endpoint validation is safe destination and
credential-use control, not an AWS IAM permission check. AWS session-token
credentials are supported; the caller must not provide the protected token
header.

## AWS-native protocol support

The relay accepts native AWS HTTP requests, not SDK operation names. The caller
must determine the endpoint, signing service, region, method, path, query,
content type, AWS-specific headers, and serialized body.

The compatibility investigation constructed and signed representative
requests from the installed AWS SDK models:

| Service | Representative administrative use |
| --- | --- |
| IAM | Inspect roles and policies; create policies; update trust policy |
| STS | Inspect caller identity |
| Lambda | Inspect/update function configuration; list functions |
| CloudWatch | Inspect/configure alarms |
| EventBridge | Inspect/manage rules |
| SNS | Inspect/configure topics |
| SQS | Inspect/configure queues |
| Secrets Manager | Inspect secrets and manage resource policies |
| SES | Inspect/manage identities and configuration sets |

These are verified compatibility examples, not a Gateman service allowlist.
Common shapes are Query/form POST (IAM, STS, SNS, classic SES), JSON-RPC POST
with `X-Amz-Target` (EventBridge, SQS, Secrets Manager), and REST-JSON (Lambda
and SES v2). CloudWatch construction was verified with the installed SDK's
effective serializer and the `monitoring` alias. Not every AWS operation has
been tested; AWS IAM and provider state remain authoritative.

## Administrative examples

These examples use illustrative resource names and no credentials. Gateman
creates the AWS `Authorization` header.

### Inspect IAM roles — Query protocol

```json
{
  "endpoint": "https://iam.amazonaws.com",
  "service": "iam",
  "region": "us-east-1",
  "method": "POST",
  "path": "/",
  "headers": {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"},
  "body": "Action=ListRoles&Version=2010-05-08",
  "body_encoding": "utf8"
}
```

Parse the native response and follow any IAM pagination marker with a new
request.

### Inspect Lambda configuration — REST-JSON

```json
{
  "endpoint": "https://lambda.eu-central-1.amazonaws.com",
  "service": "lambda",
  "region": "eu-central-1",
  "method": "GET",
  "path": "/2015-03-31/functions/gateman-example/configuration",
  "headers": {},
  "body": "",
  "body_encoding": "utf8"
}
```

The function name is part of the native path. Encode path components according
to applicable AWS API rules before signing; do not put a query string in path.

### Configure an EventBridge rule — JSON RPC

```json
{
  "endpoint": "https://events.eu-central-1.amazonaws.com",
  "service": "events",
  "region": "eu-central-1",
  "method": "POST",
  "path": "/",
  "headers": {
    "Content-Type": "application/x-amz-json-1.1",
    "X-Amz-Target": "AWSEvents.PutRule"
  },
  "body": "{\"Name\":\"gateman-example-rule\",\"State\":\"ENABLED\",\"Description\":\"Managed by example application\"}",
  "body_encoding": "utf8"
}
```

`PutRule` is a configuration mutation. AWS IAM must authorize it, and the
application should read the rule afterward to verify state.

## Response contract

For a response within the transport limit, Gateman returns the native AWS HTTP
status and raw response body. There is no Gateman success envelope and no
automatic JSON, XML, text, or binary interpretation. AWS 4xx and 5xx responses
are returned with their native status and body.

Only these provider headers are forwarded when present: `content-type`,
`content-encoding`, `etag`, `location`, `retry-after`, `ratelimit`,
`ratelimit-policy`, `x-amzn-requestid`, `x-amz-request-id`, `x-request-id`, and
`cf-ray`. Gateman does not forward every AWS response header.

The caller must interpret service-specific responses and errors, implement
pagination, and decide whether and how to retry. Redirects are disabled. The
transport disables decompression and counts the received encoded
representation toward the 4 MiB response ceiling; the cap is not necessarily
the decompressed content size.

## Credentials and IAM authorization

The application-scoped encrypted AWS relay credentials are:

- `AWS_RELAY_ACCESS_KEY_ID`
- `AWS_RELAY_SECRET_ACCESS_KEY`
- optional `AWS_RELAY_SESSION_TOKEN`

Gateman retrieves them internally and never returns them through
`/aws/request`. This capability does not require `secrets:read`; generic
stored-secret retrieval is a separate authorization path. The caller cannot
replace the configured credential or generated SigV4 headers. AWS IAM decides
whether the selected credential may perform the requested action and resource.

## Dedicated capability boundaries

- S3 object `GET` and `PUT`, including multipart object transfers, must use
  Gateman's dedicated S3 presigning capability.
- SES sending (`SendEmail`, `SendRawEmail`, `SendTemplatedEmail`, and
  `SendBulkEmail`) must use Gateman email sending capabilities.
- Lambda deployment-package and layer transfer paths must not use this relay.
- S3 bucket configuration, SES identity/configuration, and Lambda
  configuration are administrative uses and are not blanket-blocked.
- AWS SMS has a dedicated Gateman capability, but no blanket SMS-specific
  exclusion exists in this generic relay; use the dedicated capability for
  SMS product behavior.

Do not infer an AWS service allowlist from these boundaries. A request still
requires a valid native AWS representation and AWS IAM authorization.

## Request and response limits

| Limit | Value |
| --- | ---: |
| Outer Gateman JSON envelope | 1,572,864 bytes (1.5 MiB) |
| Decoded native AWS request body | 1,048,576 bytes (1 MiB) |
| Provider response body | 4,194,304 bytes (4 MiB) |
| Request headers | 16 KiB |
| Path and encoded query | 2,048 bytes each |
| Provider connect timeout | 5 seconds |
| Provider total timeout | 20 seconds |

Redirects, streaming, and multipart transfer contracts are unsupported. These
are Gateman limits, separate from AWS quotas and limits.

## Operation accounting and concurrency

The billable operation is `aws.request`. One admitted invocation consumes one
operation whether AWS succeeds, returns an error, or execution becomes
indeterminate. Authentication, validation, purpose-built exclusion,
pre-admission concurrency, and monthly allowance rejections do not consume an
operation. Credential, signing, network, transport, oversized-response, and
AWS 4xx/5xx failures occur after admission and consume it.

Application/provider admission may return `429` with `Retry-After`. Monthly
allowance exhaustion returns `403`. An unavailable accounting dependency
returns `503`. Internal slot counts, reservation implementation, database
tables, and stale-reservation recovery are not public contract.

## Error matrix

| Condition | Response | Accounting | Execution meaning |
| --- | --- | --- | --- |
| Invalid Contract v1 auth or missing scope | `401` Gateman JSON | Before admission; no operation | AWS was not called. |
| Authentication dependency unavailable | `503` Gateman JSON | Before admission; no operation | AWS was not called. |
| Invalid JSON | `400` Gateman JSON | Before admission; no operation | AWS was not called. |
| Oversized outer envelope | `413` Gateman JSON | Before admission; no operation | AWS was not called. |
| Invalid endpoint/service/region/method/path/query/header/body | `400` Gateman JSON | Before admission; no operation | AWS was not called. |
| S3/SES/Lambda purpose-built exclusion | `400` Gateman JSON | Before admission; no operation | AWS was not called. |
| Provider concurrency rejection | `429`, normally with `Retry-After` | Before accounting; no operation | AWS was not called. |
| Provider guard unavailable | `503` Gateman JSON | Before accounting; no operation | AWS was not called. |
| Monthly allowance exhausted | `403` with `monthly_operation_limit_reached` | Before reservation; no operation | AWS was not called. |
| Accounting unavailable | `503` Gateman JSON | No usable admission | AWS was not called. |
| Missing credentials or credential-store failure | `502` `AWS provider unavailable` | After admission; consumed | AWS may not have been called. |
| Signing, connection, or timeout failure | `502` `AWS provider unavailable` | After admission; consumed | AWS execution may be uncertain. |
| Response exceeds 4 MiB | `502` `Provider response exceeded Gateman transport limits` | After admission; consumed | AWS may already have executed. |
| AWS returns 4xx or 5xx | Native AWS status/body | After admission; consumed | AWS returned a response. |

Gateman-generated JSON commonly has `{ "ok": false, "error": "..." }`, but
native AWS responses do not use that envelope and there is no universal
Gateman error-code namespace.

## Provider execution uncertainty

A timeout, connection failure after request transmission, or oversized
response can produce `502` even if AWS received or executed the request. A
local signing failure occurs before the request is sent. It is not proof that
an AWS mutation was rejected. Do not blindly retry. Inspect resource state,
use an AWS-native idempotency token where supported, distinguish AWS HTTP
errors from Gateman transport errors, and verify state after mutations.
The optional `X-GM-Idempotency-Key` does not provide AWS replay protection.
Gateman does not automatically retry, paginate, or reconcile AWS operations.

## Environment behaviour

This capability is environment-independent: there is no `environment` field,
no staging/development credential selection, and no `APP_ENVIRONMENT` value
injected by Official clients. The effective AWS account, partition, region,
and permissions are determined by the supplied endpoint, SigV4 fields, and
configured credentials, subject to validation and AWS IAM.

## Implementation outcome for agents

An integration should authenticate with Contract v1 and `aws:use`, determine
the required native AWS operation, construct its exact HTTP representation,
call `POST /aws/request`, interpret the native response, handle pagination and
throttling, use AWS-native idempotency where supported, verify mutations, and
avoid blind retries after uncertain execution. Keep AWS credentials out of
source, prompts, logs, and client-side payloads.

## Implementation instructions for agents

- MUST use Contract v1 authentication and the `aws:use` scope.
- MUST call `POST /aws/request` with the documented outer JSON fields.
- MUST construct the provider-native AWS request; Gateman does not translate
  SDK operation names into HTTP requests.
- MUST supply endpoint, SigV4 service, region, method, path, query, headers,
  and serialized body correctly.
- MUST represent JSON and Query bodies as strings, using `utf8` or strict
  base64 as appropriate.
- MUST NOT supply protected SigV4 or transport headers.
- MUST treat AWS IAM as authoritative for action and resource permission.
- MUST respect the S3 object, SES sending, and Lambda deployment boundaries.
- MUST handle native AWS statuses, bodies, pagination, throttling, and errors.
- MUST use AWS-native idempotency where the selected mutation supports it.
- MUST NOT blindly retry timeouts, connection failures, or oversized responses.
- MUST account for one consumed `aws.request` operation after admission.
- MUST keep AWS credentials confidential.

## Reusable AGENTS.md block

```markdown
<!-- gateman:begin capability=aws.use -->
Use AWS through Gateman's authenticated Contract v1 relay. The application
MUST hold `aws:use` and MUST call `POST /aws/request`.

The outer JSON object uses `endpoint`, `service`, `region`, optional `method`,
`path`, optional `query`, optional `headers`, optional string `body`, and
optional `body_encoding` (`utf8` or strict `base64`). JSON and AWS Query bodies
MUST be serialized into `body`. The caller constructs the provider-native AWS
request; Gateman performs SigV4 signing with protected credentials.

AWS IAM authorizes the requested AWS action and resource. Do not send AWS
credentials in source, prompts, logs, or request payloads. Do not provide
protected SigV4 or transport headers. S3 object transfers, SES sending, and
Lambda deployment-package/layer transfers use dedicated boundaries.

The envelope is limited to 1.5 MiB, the decoded request body to 1 MiB, the
response body to 4 MiB, headers to 16 KiB, and path and encoded query to 2,048
bytes each.
Gateman does not automatically retry or paginate. Interpret native AWS
responses, handle pagination/throttling, and use AWS-native idempotency where
supported. A timeout, connection failure, or oversized response can be
uncertain: inspect AWS state before retrying a mutation. One admitted
invocation consumes one `aws.request` operation.

Full reference: https://docs.getgateman.com/capabilities/aws.use/
<!-- gateman:end capability=aws.use -->
```

## Related references

- [Contract v1](https://docs.getgateman.com/contract-v1/)
- [Authentication and signing](https://docs.getgateman.com/authentication/)
- [Operation Accounting](https://docs.getgateman.com/operation-accounting/)
- [Rate limits and concurrency](https://docs.getgateman.com/rate-limits-and-concurrency/)
- [Idempotency](https://docs.getgateman.com/idempotency/)
- [Errors and responses](https://docs.getgateman.com/errors-and-responses/)
- [Official PHP client](https://docs.getgateman.com/canonical-client-php/)
- [Official Node.js client](https://docs.getgateman.com/canonical-client-node/)
- [Official Python client](https://docs.getgateman.com/canonical-client-python/)
- [Official Go client](https://docs.getgateman.com/canonical-client-go/)
- [AWS Signature Version 4 documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html)
