> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cynative.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS Connector: Credential Discovery and Read-Only Hardening

> Configure Cynative's AWS connector: credential chain, STS credential downscoping to SecurityAudit, region selection, and EKS cluster access.

The AWS connector signs requests to AWS service APIs with SigV4 and is the only Cynative connector that provides both a client-side action gate **and** an AWS-side credential boundary (for assumed-role identities). The EKS connector registers alongside it, sharing the same AWS credentials.

**Connector id:** `aws`\
**EKS connector id:** `eks`

## Quick start

Run Cynative from a shell where the AWS SDK default credential chain can retrieve credentials:

```bash theme={null}
aws sts get-caller-identity
cynative -p "list public S3 buckets in my AWS account"
```

## Credential discovery

Cynative loads AWS config through the AWS SDK default credential chain and probes credential retrieval. The SDK can use standard sources such as environment variables, shared config and credentials files, SSO-backed profiles, web identity, ECS credentials, and EC2 instance roles. The SDK chain reads these variables — Cynative does not read them to authenticate; it inspects some only as a startup presence signal:

* `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` — selects the named shared-config/credentials profile (also implies the target account).
* `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN` — static or temporary credentials.
* `AWS_ROLE_ARN` / `AWS_WEB_IDENTITY_TOKEN_FILE` — web-identity role to assume.
* `AWS_CONFIG_FILE` / `AWS_SHARED_CREDENTIALS_FILE` — override the `~/.aws/config` and `~/.aws/credentials` paths.
* `AWS_CA_BUNDLE` — TLS CA bundle for Cynative's **own** AWS control calls (credential retrieval, STS `AssumeRole`, IAM policy fetch). It is **not** applied to the guarded transport that serves the model's `http_request` calls.

### Registration and validation

Cynative eagerly validates the credential at startup with `sts:GetCallerIdentity`. The resolved account number and caller ARN are shown in the startup connector inventory. If config loading, credential retrieval, or that identity check fails, the `aws` and `eks` connectors are not registered.

**References:**

* [AWS CLI environment variables](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)
* [AWS CLI configuration and credential files](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)

## Target selection

### Account and identity

The connector signs as whatever account/identity the AWS SDK default chain resolves — Cynative does not pick an account itself. Change the account or identity as you would for the `aws` CLI: use `export AWS_PROFILE=<name>`, set static credentials, point at a role, or relocate the credential files. Verify with `aws sts get-caller-identity`.

### Region per request

Region is supplied per request via `aws_auth.region`. A regional endpoint requires the region to be present and to match the request host; a partition-global endpoint (such as IAM or global STS) accepts an empty or canonical region. When the region is **omitted** for a global endpoint, signing falls back to the SDK-resolved region (`AWS_REGION` / `AWS_DEFAULT_REGION` / profile, default `us-east-1`). A region you do supply is used as given.

Change the default region with `AWS_REGION` (which overrides `AWS_DEFAULT_REGION`), or have the model pass `aws_auth.region` per request.

## Request usage

Use `auth_provider: "aws"` and include an `aws_auth` object:

```json theme={null}
{
  "aws_auth": {
    "service": "ec2",
    "region": "us-east-1"
  }
}
```

`aws_auth.service` is required. `aws_auth.region` should be supplied for regional endpoints and must match the request host.

**Minimal example:**

```javascript theme={null}
const resp = await http_request({
  method: "GET",
  url: "https://sts.us-east-1.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15",
  headers: [],
  body: "",
  auth_provider: "aws",
  aws_auth: { service: "sts", region: "us-east-1" }
});
console.log(resp.body);
```

## Hardening

### Credential downscoping (assumed-role identities)

For **assumed-role identities**, Cynative re-vends credentials via STS `AssumeRole` for a one-hour session scoped to the configured policy (default `arn:aws:iam::aws:policy/SecurityAudit`). The resulting permission set is the role's policies intersected with the configured policy. With the default `SecurityAudit` policy, AWS IAM becomes a server-side backstop: if a mutating action slips past the client-side action gate, the scoped credential normally cannot perform it.

**IAM-user and root identities run unscoped** — Cynative uses their base credentials directly. They are gated solely by the client-side host-pinning and action-authorization checks; there is no AWS-side credential backstop for those identities.

Cynative no longer mints `GetFederationToken` sessions. Federated-user callers are not supported (see [Limitations](#limitations)).

### Host pinning

Cynative maps AWS request hosts to an AWS service and region before signing. It rejects unsupported hosts, IP literals, localhost, and VPC endpoints. The request host must match the model-supplied `aws_auth.service` and `aws_auth.region`, preventing a model-authored request from claiming one AWS target while sending credentials to another.

### Action authorization

Before signing, Cynative classifies the AWS operation, resolves the IAM action(s) required for it, and checks them against the configured policy with `iam:SimulateCustomPolicy`. The gate fails closed: if Cynative cannot resolve a required action, the request is denied.

The resolver uses three sources in order: AWS Service Reference API, iam-dataset, then `namespace:op` derivation. `iam:SimulateCustomPolicy` must be available to the launching credentials; if it is denied, the gate fails closed.

One operation is pinned without policy simulation: `sts:GetCallerIdentity` (AWS documents it as requiring no permissions). All other operations must clear the configured policy.

### Response redaction

Cynative redacts secret-shaped content and credential-named fields from responses before the model sees them. The default `SecurityAudit` policy also avoids direct secret-value APIs such as `secretsmanager:GetSecretValue`, `kms:Decrypt`, `ssm:GetParameter`, and `ec2:GetPasswordData`. Redaction is a defense-in-depth layer — treat returned AWS data as sensitive.

### Reading the startup posture

The AWS connector line in the startup inventory shows the enforcement mode, configured policy, and resolved identity:

```text theme={null}
✓ aws    access=default(read-only) · enforced=client+aws · policy=arn:aws:iam::aws:policy/SecurityAudit · 774148217555 · arn:…/role · (+eks)
```

* `access=default(read-only)` — the curated `SecurityAudit` default is in force; `access=custom` for any other policy.
* `enforced=client` — host pinning and action gate only (IAM-user / root identities, or a degraded assumed-role scope).
* `enforced=client+aws` — client-side gate **plus** an STS-scoped session; both boundaries are active.
* `enforced=client+aws(unverified)` — the eager STS probe could not pre-confirm the scope; it resolves at first request. If that resolution degrades to unscoped, Cynative emits a `⚠️ aws_hardening: cred_scope degraded to disabled (reason=…)` warning to stderr.
* `(+eks)` — the EKS connector is folded in.

## Cynative configuration

The IAM policy the action gate enforces (for all identities), and — for assumed-role identities — the STS session scope. Default `arn:aws:iam::aws:policy/SecurityAudit`.

```yaml theme={null}
connectors:
  aws:
    policy: arn:aws:iam::aws:policy/SecurityAudit
```

```bash theme={null}
export CYNATIVE_CONNECTORS_AWS_POLICY=arn:aws:iam::aws:policy/SecurityAudit
```

A custom policy ARN is configured the same way:

```yaml theme={null}
connectors:
  aws:
    policy: arn:aws:iam::123456789012:policy/MyReadOnlyPolicy
```

A configured policy that the caller cannot read (`iam:GetPolicy` / `iam:GetPolicyVersion` denied) causes the `aws` and `eks` connectors to fail registration at startup with a clear reason.

### Cache settings

AWS hardening metadata (service models and action registries) is cached under `<cache.dir>/aws`. The cache is shared across connectors.

```yaml theme={null}
cache:
  dir: ~/.cynative/cache
  ttl: 24h
```

***

## EKS connector

The EKS connector provides Kubernetes API access to Amazon EKS clusters. It registers alongside the `aws` connector, sharing the same AWS credentials.

**Connector id:** `eks`

### How it works

Cynative inherits AWS credentials from the SDK default chain. For each request it:

1. Resolves the cluster endpoint and CA data via the EKS `DescribeCluster` API (requires `eks:DescribeCluster` on the target cluster).
2. Presigns an STS `GetCallerIdentity` request to build the Kubernetes bearer token expected by the EKS authenticator.
3. Applies the shared Kubernetes hardening model (host pinning, `view` RBAC gate, dial-time IP authorization, response redaction).

The EKS-specific cluster endpoint, CA, and bearer token are resolved **per request** (not at registration). Registration is gated solely on the same eager AWS validation as the `aws` connector.

### Request usage

Use `auth_provider: "eks"` and include an `eks_auth` object:

```json theme={null}
{
  "eks_auth": {
    "cluster_name": "prod",
    "region": "us-east-1"
  }
}
```

`eks_auth.cluster_name` is required (1–100 letters, digits, hyphens, or underscores, starting with a letter or digit). `eks_auth.region` defaults to the SDK-configured AWS region, then `us-east-1`.

```javascript theme={null}
const resp = await http_request({
  method: "GET",
  url: "https://EXAMPLE.gr7.us-east-1.eks.amazonaws.com/api",
  headers: [],
  body: "",
  auth_provider: "eks",
  eks_auth: { cluster_name: "prod", region: "us-east-1" }
});
console.log(resp.body);
```

### Configuring the ClusterRole

The read-only ClusterRole the EKS connector authorizes against is configurable (default `view`):

```yaml theme={null}
connectors:
  eks:
    cluster_role: view
```

```bash theme={null}
export CYNATIVE_CONNECTORS_EKS_CLUSTER_ROLE=view
```

Widening the role past `view` widens Cynative's permitted verbs — including writes. See the shared [Kubernetes hardening model](/connectors/kubernetes) for full details.

## Defense at a glance (AWS + EKS)

| Control | AWS | EKS |
| - | - | - |
| Read-only by default | ✓ | ✓ |
| Enforcement model | IAM action simulation against configured policy | live `view` ClusterRole (kube-apiserver-style classification) |
| Configurable exposure | ✓ any IAM policy ARN (default `SecurityAudit`) | ✓ `connectors.eks.cluster_role` (default `view`) |
| Credential downscoping | ✓ STS-scoped — assumed-role identities only | — · authn/authz decoupled in Kubernetes |
| Host pinning | ✓ (host → service/region; rejects IP literals, localhost, VPC endpoints) | ✓ (cluster endpoint from `DescribeCluster`) |
| Dial-time IP authorization | ✓ (default internal-range deny) | ✓ (dialed IP must be in the resolved endpoint IP set) |
| Model-supplied-credential rejection | ✓ | ✓ |
| Response redaction | ✓ | ✓ |

## Limitations

* **Credential downscoping (assumed-role)** is best-effort. An unrecognized caller ARN or a self-assumption denial degrades the STS scope to disabled; the inventory line shows `enforced=client` and a `⚠️ aws_hardening: cred_scope degraded` warning is printed to stderr. IAM-user and root identities always show `enforced=client` by design.
* **Federated-user callers** are not supported. A federated-user session cannot call IAM APIs (`iam:GetPolicy`, `iam:GetPolicyVersion`), which are required for hardening initialization. Switch to an IAM-user or assumed-role identity.
* **Custom policy ARNs** that the caller cannot read (`iam:GetPolicy` / `iam:GetPolicyVersion` denied) fail connector registration at startup.
* **The assumed-role path** re-assumes the underlying role with Cynative's configured `PolicyArns`; it does not inherit a session policy that may already narrow the current shell session.
* **Session policies** are not an absolute ceiling against every resource-based policy. An S3 bucket or KMS key policy that grants directly to the STS session principal can bypass the session policy boundary.
* **`SecurityAudit` is read-oriented, not strictly side-effect-free.** It includes a few audit-support actions with benign side effects, such as `iam:GenerateCredentialReport` and `config:DeliverConfigSnapshot`.
* **Action authorization simulates action names** against the configured policy; it does not pass per-request resource ARNs or condition context (the resource defaults to `*`). For IAM-user and root identities, a policy whose read-only intent depends on resource scoping or `Deny` on specific resources is not fully enforced client-side.
* **VPC endpoints and IP-literal AWS targets** are rejected by host hardening.
* **EKS requires `eks:DescribeCluster`** on the target cluster to resolve the endpoint and CA data.
* **EKS bearer-token generation is not downscoped.** Kubernetes decouples authentication from authorization; authorization is server-side cluster RBAC. The in-process `view` gate, host pinning, and dial-time IP authorization are the client-side controls.
* The `SecurityAudit` policy can still return sensitive data through non-secret APIs, such as Lambda environment variables from `lambda:GetFunctionConfiguration`. Treat returned AWS data as sensitive.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.