Skip to content
Draft
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
204 changes: 202 additions & 2 deletions docs/connector.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ Identity Center user Last Login uses a separate CloudTrail event feed. Enable Or

Configuring the connector requires you to pass in credentials generated in AWS. Gather these credentials before you move on.

<Note>
**AWS China (`aws-cn`) accounts:** the trust policies and `arn:aws:` resource ARNs on this page are for the commercial partition and cannot be used in China. IAM in an `aws-cn` account cannot resolve the C1 principal below, and creating the role typically fails with a `MalformedPolicyDocument` error such as `Invalid principal in policy`. China is supported only with the self-hosted connector. See the **Self-hosted** tab under [Configure the AWS connector](#configure-the-aws-connector) and [AWS China IAM setup](#aws-china-iam-setup).
</Note>

<Warning>
**Important**

Expand Down Expand Up @@ -835,6 +839,10 @@ The permissions policy below is broken into several sections to align with these
<Tab title="Cloud-hosted">
**Follow these instructions to use a built-in, no-code connector hosted by C1.**

<Note>
The cloud-hosted connector does not support AWS China (`aws-cn`) accounts. It reaches your account from a C1 account in the commercial partition, and `sts:AssumeRole` cannot cross partitions. Use the **Self-hosted** tab and the [AWS China IAM setup](#aws-china-iam-setup) instead.
</Note>

<Steps>
<Step>
Return to the AWS v2 connector setup page in C1.
Expand Down Expand Up @@ -883,6 +891,10 @@ The permissions policy below is broken into several sections to align with these
<Tab title="Self-hosted">
**Follow these instructions to use the Amazon Web Services connector, hosted and run in your own environment.**

<Note>
**AWS China (`aws-cn`) accounts** must use this self-hosted option. Do Step 1 below to create the connector in C1 and get a Client ID and Secret. Skip the C1-provided External ID and C1 trust role from [Gather AWS credentials](#gather-aws-credentials), and follow [AWS China (aws-cn) partition](#aws-china-aws-cn-partition) and [AWS China IAM setup](#aws-china-iam-setup) in Step 2 instead.
</Note>

When running in service mode on Kubernetes, a self-hosted connector maintains an ongoing connection with C1, automatically syncing and uploading data at regular intervals. This data is immediately available in the C1 UI for access reviews and access requests.

### Resources
Expand Down Expand Up @@ -996,12 +1008,12 @@ ConductorOne binding account in the commercial partition into your role — can
that already live in the China partition:

- **Static China-partition access keys**, via `BATON_GLOBAL_ACCESS_KEY_ID` / `BATON_GLOBAL_SECRET_ACCESS_KEY`, or
- **IRSA** inside a China-region EKS cluster, with `BATON_ROLE_ARN` set and `BATON_GLOBAL_ROLE_ARN` left unset (single-hop assume role).
- **IRSA** inside a China-region EKS cluster, with `BATON_ROLE_ARN` set and `BATON_GLOBAL_ROLE_ARN` left unset. Whether you also set `BATON_USE_ASSUME` depends on whether the IRSA role is the connector role itself or a bootstrap role; see [Option C](#option-c-irsa-on-a-china-eks-cluster).

Set the regions to China regions so endpoints resolve to `*.amazonaws.com.cn` and credentials are
signed for the right partition:

IRSA (single-hop assume role):
IRSA where the IRSA role is the connector role (see [Option C](#option-c-irsa-on-a-china-eks-cluster) for the bootstrap-role variant that sets `BATON_USE_ASSUME`):

```yaml expandable
BATON_ROLE_ARN: arn:aws-cn:iam::<account id>:role/<role name>
Expand Down Expand Up @@ -1049,6 +1061,190 @@ Two things to confirm against your own account before rolling out:
to work unchanged — but verify events are actually returned, since a mismatch surfaces as an
empty last-login result rather than an error.

#### AWS China IAM setup

The commercial-partition setup earlier on this page does not work in `aws-cn`:

- **There is no C1-hosted trust relationship to build.** C1's binding account is in the commercial partition and `sts:AssumeRole` cannot cross partitions, so the `arn:aws:iam::765656841499:role/ConductorOneService` principal can never be trusted from an `aws-cn` account. IAM cannot resolve that principal, so creating the role typically fails with a `MalformedPolicyDocument` error such as `Invalid principal in policy`. If you are configuring the C1-hosted connector against a China account, no trust policy will work; deploy the connector in your own environment.
- **Every ARN must use the `aws-cn` partition.** Trust policy principals and permissions policy `Resource` values both need `arn:aws-cn:`. A permissions policy with a wrong-partition resource ARN can save cleanly and then silently match nothing, so an Organizations sync fails with access-denied errors that look like a permissions problem rather than a partition problem.

Pick the option that matches how your connector authenticates. Start with Option A if you only need to prove connectivity.

##### How the C1 connector settings map to a China deployment

The connector's **Settings** area in C1 is built for the cloud-hosted connector, which cannot reach an `aws-cn` account. For a self-hosted China deployment, use the settings page to rotate the Client ID and Secret (Step 1 above) and set everything else with the environment variables below.

| C1 setting | Environment variable | In China |
|---|---|---|
| **Role ARN** | `BATON_ROLE_ARN` | Use an `arn:aws-cn:` role ARN. Required for Options B and C; leave unset for Option A. |
| **External ID** | `BATON_EXTERNAL_ID` | Optional. Only sent when the connector assumes a role (Option B, or the Option C bootstrap-role variant), and it must match the trust policy if you set one. C1 generates a value for you, but you do not need to use it. |
| **Enable support for AWS Organizations** | `BATON_GLOBAL_AWS_ORGS_ENABLED` | Same as commercial. Create the role in the management account and see [child-account roles](#aws-organizations-child-account-roles). |
| **Enable support for AWS IAM Identity Center** | `BATON_GLOBAL_AWS_SSO_ENABLED` | Confirm Identity Center is available in your China account first. |
| **Region for AWS IAM Identity Center** | `BATON_GLOBAL_AWS_SSO_REGION` | Choose `cn-north-1` or `cn-northwest-1`. The default is `us-east-1`, which the connector rejects at startup in a China deployment. |
| **Also sync cross-account IAM when Identity Center is enabled** | `BATON_GLOBAL_AWS_CROSS_ACCOUNT_IAM_ENABLED` | Same as commercial. Needs the child-account roles. |
| **IAM assume role name (child IAM accounts)** | `BATON_IAM_ASSUME_ROLE_NAME` | Defaults to `OrganizationAccountAccessRole`. Child roles must have this name. |
| **Sync Secrets** | `BATON_SYNC_SECRETS` | Same as commercial. |
| **Sync IAM User Console Access** | `BATON_SYNC_IAM_USER_CONSOLE_ACCESS` | Same as commercial. Needs `iam:GetLoginProfile` in the `arn:aws-cn:` permissions policy. |
| **Sync Resource Tags** | `BATON_SYNC_RESOURCE_TAGS` | Same as commercial. Needs the tag permissions in the `arn:aws-cn:` permissions policy. |
| **Sync SSO User Last Login** | `BATON_SYNC_SSO_USER_LAST_LOGIN` | Same as commercial. Needs `cloudtrail:LookupEvents`. |
| **Sync Only Attached Policies** | `BATON_SYNC_ONLY_ATTACHED_POLICIES` | Same as commercial. No extra permission. |
| **Account Provisioning Target** | `BATON_CREATE_ACCOUNT_RESOURCE_TYPE` | Same as commercial. No extra permission. |

Some settings have no field in the C1 UI and exist only as environment variables. They are the ones that select the China partition and credentials: `BATON_GLOBAL_REGION` (set to `cn-north-1` or `cn-northwest-1`), `BATON_GLOBAL_ACCESS_KEY_ID`, `BATON_GLOBAL_SECRET_ACCESS_KEY` and `BATON_USE_ASSUME`. `BATON_GLOBAL_ROLE_ARN` is also environment-only and must stay unset.

##### Permissions policy

Use the permissions policy from the **Grant permission for data sync** step of the IAM setup or Identity Center setup above, with the partition changed in every `Resource` ARN. The resource-scoped statements become:

```json
"Resource": "arn:aws-cn:iam::*:role/aws-reserved/sso.amazonaws.com/*"
"Resource": "arn:aws-cn:iam::*:saml-provider/AWSSSO_*_DO_NOT_DELETE"
"Resource": "arn:aws-cn:iam::*:role/OrganizationAccountAccessRole"
```

If you use a custom `BATON_IAM_ASSUME_ROLE_NAME`, use that role name in the last ARN instead. Attach the policy to the identity the connector ends up running as: the IAM user in Option A, or the connector role in Options B and C. The same changes apply to the Terraform copies of these policies.

##### Option A: static access keys (no trust policy)

Create an IAM user in your China account, attach the permissions policy above, and create an access key. No trust policy and no role are involved.

```yaml expandable
BATON_GLOBAL_ACCESS_KEY_ID: <access key id>
BATON_GLOBAL_SECRET_ACCESS_KEY: <secret access key>
BATON_GLOBAL_REGION: cn-north-1
# Only when Identity Center support is enabled
BATON_GLOBAL_AWS_SSO_REGION: cn-north-1
```

##### Option B: keys or an instance profile that assume a connector role

This keeps the role model used elsewhere in these docs. Create a role named for example `BatonAWSConnector`, attach the permissions policy to it, and give it this trust policy. The principal is an identity inside your own `aws-cn` account, such as the IAM user from Option A or the instance role the connector runs as:

```json expandable
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BatonSelfHostedAssume",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::<ACCOUNT_ID>:user/baton-aws"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "<ANY_SHARED_VALUE>" }
}
}
]
}
```

If the connector runs on an EC2 instance or other compute with an instance profile, use that instance role as the principal instead: `arn:aws-cn:iam::<ACCOUNT_ID>:role/<INSTANCE_ROLE_NAME>`.

The `sts:ExternalId` condition is optional here. It protects against a confused deputy across a third party, and there is no third party when the connector runs in your own environment. If you keep it, `BATON_EXTERNAL_ID` must match. In single-hop mode the connector does not enforce the 32-64 character external ID length rule, so any matching value works.

```yaml expandable
# Credentials of the IAM user named in the trust policy.
# Omit both keys if the connector runs with an instance profile; the ambient
# credentials are then used to assume the role.
BATON_GLOBAL_ACCESS_KEY_ID: <access key id>
BATON_GLOBAL_SECRET_ACCESS_KEY: <secret access key>
BATON_USE_ASSUME: "true"
BATON_ROLE_ARN: arn:aws-cn:iam::<ACCOUNT_ID>:role/BatonAWSConnector
BATON_EXTERNAL_ID: <same value as the trust policy; omit if you removed the condition>
BATON_GLOBAL_REGION: cn-north-1
# Only when Identity Center support is enabled
BATON_GLOBAL_AWS_SSO_REGION: cn-north-1
# Leave BATON_GLOBAL_ROLE_ARN unset. Setting it selects the two-hop, C1-hosted path.
```

Without the access keys, the connector falls back to the ambient AWS credential chain. If you followed this option with an IAM user, the assume-role call then fails without any hint that the keys are missing.

##### Option C: IRSA on a China EKS cluster

Use a web identity trust policy, not the cross-account one. There is no `sts:ExternalId` condition on this shape.

```json expandable
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws-cn:iam::<ACCOUNT_ID>:oidc-provider/<ISSUER_HOST>/id/<ID>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"<ISSUER_HOST>/id/<ID>:sub": "system:serviceaccount:<NAMESPACE>:<SERVICE_ACCOUNT>",
"<ISSUER_HOST>/id/<ID>:aud": "<AUDIENCE>"
}
}
}
]
}
```

Read the issuer host from your own cluster rather than copying commercial-partition values:

```bash
aws eks describe-cluster --name <cluster> --region cn-north-1 --query cluster.identity.oidc.issuer
```

Do not assume the audience. Check the `ClientIDList` of the IAM OIDC provider in your China account and use that value for `:aud`; it may differ from the commercial `sts.amazonaws.com`.

```yaml expandable
BATON_ROLE_ARN: arn:aws-cn:iam::<ACCOUNT_ID>:role/BatonAWSConnector
BATON_GLOBAL_REGION: cn-north-1
# Only when Identity Center support is enabled
BATON_GLOBAL_AWS_SSO_REGION: cn-north-1
# Leave BATON_USE_ASSUME and BATON_GLOBAL_ROLE_ARN unset.
```

This assumes the role bound to the service account is the connector role itself. Do not set `BATON_USE_ASSUME` in that case. IRSA already supplies credentials for `BatonAWSConnector` through the default credential chain. With `BATON_USE_ASSUME` set, the connector would call `sts:AssumeRole` into that same role, which IAM denies unless the trust policy explicitly allows the role to assume itself. `BATON_ROLE_ARN` is still set so the connector can determine its partition and account.

If instead IRSA gives the pod a separate bootstrap role that assumes a distinct connector role, set `BATON_USE_ASSUME: "true"` and point `BATON_ROLE_ARN` at the connector role. That role's trust policy must then trust the bootstrap role (`"AWS": "arn:aws-cn:iam::<ACCOUNT_ID>:role/<BOOTSTRAP_ROLE>"`, action `sts:AssumeRole`) rather than the OIDC provider, and the bootstrap role needs permission to call `sts:AssumeRole` on it.

##### AWS Organizations: child-account roles

When AWS Organizations support is enabled, the connector assumes a role in each child account. Create it in each child account where it does not already exist, with this trust policy, using the management account's connector role as the principal. AWS Organizations creates `OrganizationAccountAccessRole` automatically in accounts created through Organizations and it already trusts the management account, so for those accounts there is nothing to create. You need to create it for invited accounts, or when you use a custom `BATON_IAM_ASSUME_ROLE_NAME`:

```json expandable
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BatonCrossAccount",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws-cn:iam::<MANAGEMENT_ACCOUNT_ID>:role/BatonAWSConnector"
Comment thread
marcuswhitaker-c1 marked this conversation as resolved.
Resolved
},
"Action": "sts:AssumeRole"
}
]
}
```

The principal above fits Options B and C, where the connector runs as `BatonAWSConnector`. With Option A (static keys), the child-account `AssumeRole` call is signed by the IAM user, so use that user as the principal instead: `arn:aws-cn:iam::<MANAGEMENT_ACCOUNT_ID>:user/<USER_NAME>`.

A role you create yourself also needs the permissions the connector uses in that account: attach the same permissions policy described above. Without it the role can be assumed but cannot read anything. The role AWS creates automatically carries `AdministratorAccess`, so it already works.

Two requirements that are easy to miss:

- **The role name must be `OrganizationAccountAccessRole`**, unless you set `BATON_IAM_ASSUME_ROLE_NAME` to a different name.
- **Do not add an `sts:ExternalId` condition.** The connector does not send an external ID on the child-account hop, only a session name and duration. Copying the external ID condition from the commercial trust policy onto the child roles makes every child account fail with `AccessDenied` partway through a sync.

The connector builds the child-account role ARN in its own partition, so this works unchanged in `aws-cn`.

##### Other China-specific things to check

- **Region value.** IAM and Organizations use a single endpoint per partition, which the AWS SDK resolves to `iam.cn-north-1.amazonaws.com.cn` and `organizations.cn-northwest-1.amazonaws.com.cn` whichever China region you choose. Either `cn-north-1` or `cn-northwest-1` works for `BATON_GLOBAL_REGION`; it only has to start with `cn-` (lowercase). Set it in every shape, including role-based ones: with a role ARN and no region, the startup check has nothing to compare and the SDK falls back to whatever region the environment provides.
- **Identity Center region.** The Identity Center, identity store and CloudTrail last-login clients are only created when both Organizations and Identity Center support are enabled, but the startup partition check runs whenever Identity Center is enabled. Set `BATON_GLOBAL_AWS_SSO_REGION` to a China region in either case.
- **AWS managed policies.** AWS-managed policies appear as `arn:aws-cn:iam::aws:policy/...` in China. The connector treats them as global objects, the same as in the commercial partition, so no configuration is needed.
- **Container image.** The sample Deployment pulls `public.ecr.aws/conductorone/baton-aws`. Confirm your China cluster can reach that registry, and mirror the image into a registry it can reach if not.
- **Network access.** The connector needs outbound access to C1 and to the `*.amazonaws.com.cn` endpoints for IAM, STS and Organizations. Confirm your China network and egress rules allow both.
- **STS actions.** The `assume_role_with_web_identity` and `issue_federation_token` actions have not been exercised against `aws-cn`. Web identity additionally needs AWS China STS to be able to reach C1's OIDC issuer, and `GetFederationToken` needs long-term IAM user keys (Option A).

See the connector's README or run `--help` to see all available configuration flags and environment variables.

#### Deployment configuration
Expand Down Expand Up @@ -1102,6 +1298,10 @@ spec:

**Use the following Terraform script to integrate your AWS instance with C1.**

<Note>
This script creates the cloud-hosted trust relationship with C1's commercial-partition account, so it does not work for AWS China (`aws-cn`) accounts. For China, use the **Self-hosted** tab and the [AWS China IAM setup](#aws-china-iam-setup).
</Note>

### Step 1: Get C1-provided External ID for AWS IAM Role

<Steps>
Expand Down
Loading