Connect Amazon Connect
Bring your contact center onto the operational picture. The cn-amazon-connect connector senses the contact event stream, contact trace records, and the call recordings that land in your instance's S3 bucket, and acts by syncing call status onto the customer record in your CX platform, idempotently. Authentication is a cross-account IAM role; no long-lived keys leave your account.
How the connector works
The connector subscribes to your instance's contact event stream, so calls appear as they begin, transfer, and end, not minutes later. Once a call completes, its contact trace record brings queue, agent, and duration detail. Recordings continue landing in your own S3 bucket exactly as they do today; Fibric reads them there rather than copying them out, and pickup is idempotent, so a re-delivered notification never produces a duplicate on the timeline.
Every contact event becomes a tenant-scoped event envelope, stamped with tenant_id and source on the way in and carrying a dotted noun.verb event type that operators subscribe to. Sensing never acts by itself: an event can only cause an operator to propose a plan, and the deterministic executor disposes that plan under your trust policy. The connector runs in production today under BearScope, Fibric's flagship product.
| Event type | When it is emitted | Payload highlights |
|---|---|---|
contact.initiated | A call begins, inbound or outbound. | contact_id, channel, queue |
contact.connected | The contact is connected to an agent. | contact_id, agent |
contact.transferred | The contact is transferred to another queue or agent. | contact_id, from, to |
contact.disconnected | The call ends, for any reason. | contact_id, duration, disconnect_reason |
contact.trace.available | The contact trace record is ready after completion. | contact_id, queue, agent, duration |
recording.available | A recording object lands in the instance's S3 bucket. | contact_id, s3_uri |
Acting, the connector exposes two governed writes: calls.status-sync, which syncs call status onto the customer record in your CX platform of record, and contact-attribute updates on a contact within the limits you set. Both route through the executor, carry idempotency keys, and leave receipts.
Prerequisites
- An Amazon Connect instance with call recording writing to its S3 bucket.
- The contact event stream enabled on the instance (step 1 below covers this).
- Permission to create an IAM role in the AWS account that owns the instance.
- A Fibric workspace and the CLI installed and authenticated; see Installation.
- For the status-sync step: a CX platform connector already installed, for example
cn-kustomer; see Connect Kustomer.
Enable the contact event stream
Amazon Connect publishes contact events, initiated, connected, transferred, disconnected, through an EventBridge or Kinesis stream attached to the instance. This stream is the feed the connector senses, and it must be enabled before anything else on this page works.
In the Amazon Connect console, open your instance, then Data streaming, and enable contact event streaming. Amazon Connect delivers contact events to the default EventBridge bus in the instance's account; if you prefer Kinesis, attach a Kinesis data stream instead and note its ARN, you will scope the IAM role to it in the next step. Contact trace records follow each completed call on the same data-streaming configuration.
Nothing about your recording pipeline changes. Recordings keep landing in the instance's S3 bucket under the prefix Connect already writes to, typically connect/<instance-alias>/CallRecordings/. Fibric reads objects there when a recording.available reference resolves; it never copies recordings out of your account or asks you to re-route them.
Create the cross-account IAM role
Authentication is a cross-account IAM role scoped to the Connect instance and the recording bucket, assumed by Fibric for each read. No long-lived keys leave your account: there is nothing to rotate, nothing to leak, and revoking access is deleting the role. Two policies define the role.
Trust policy
The trust policy lets Fibric's connector runtime assume the role, and only with the external id issued for your workspace. The sts:ExternalId condition prevents a confused-deputy path: even a caller from Fibric's account cannot assume your role without presenting the id bound to your tenant. Find your external id under Settings → Connections in the console, or with fibric connectors add amazon-connect --show-external-id.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "FibricAssumeRole",
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::999988887777:role/fibric-connector-runtime" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "fib-ext-t8f2ac901-7d41" }
}
}
]
}
Permissions policy
The permissions policy grants read access to exactly three things: contact metadata on your instance, the event stream, and the recording prefix in the bucket. Scope every resource to the instance ARN and the bucket prefix; nothing here needs * resources or write access to your AWS account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SenseContactEvents",
"Effect": "Allow",
"Action": ["connect:DescribeContact", "connect:ListContactEvents"],
"Resource": "arn:aws:connect:us-east-1:111111111111:instance/YOUR_INSTANCE_ID/*"
},
{
"Sid": "ReadEventStream",
"Effect": "Allow",
"Action": ["kinesis:DescribeStream", "kinesis:GetShardIterator", "kinesis:GetRecords"],
"Resource": "arn:aws:kinesis:us-east-1:111111111111:stream/connect-contact-events"
},
{
"Sid": "ReadRecordings",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::your-connect-recordings",
"arn:aws:s3:::your-connect-recordings/connect/*"
]
}
]
}
The ReadEventStream statement above is for a Kinesis data stream. If your instance streams contact events to EventBridge instead, replace it with an EventBridge rule in your account that forwards contact events to the endpoint the connector gives you at configure time; the role then needs no kinesis:* actions at all. Either way, keep the resource scoped to this one instance's stream, never a wildcard.
Install and configure the connector
Add the connector and bind it to the telephony role. Operators ask for telephony capabilities, not for Amazon Connect by name, so a future move to another voice platform is a rebinding, not a rewrite. See Connectors for how capability binding works.
# install and bind to the telephony role
fibric connectors add amazon-connect --as telephony
# supply the role Fibric should assume and the instance to scope to
fibric connectors configure amazon-connect \
--role-arn arn:aws:iam::111111111111:role/fibric-connect-reader \
--instance-id YOUR_INSTANCE_ID \
--region us-east-1 \
--recording-bucket your-connect-recordings \
--recording-prefix connect/
# confirm the capabilities it now exposes
fibric capabilities ls
Configuration parameters:
| Parameter | Required | Description |
|---|---|---|
--role-arn | yes | The cross-account role from step 2. Fibric assumes it for each read; it is never cached beyond the STS session. |
--instance-id | yes | The Connect instance id. Events from any other instance in the account are refused, even if the role would permit them. |
--region | yes | The AWS region the instance runs in. |
--recording-bucket | yes | The S3 bucket call recordings land in. |
--recording-prefix | no | Key prefix for recordings. Defaults to connect/. Reads outside this prefix never happen, matching the IAM scope. |
--attribute-allowlist | no | Contact attributes the connector may update, comma-separated. Empty by default: with no allowlist, attribute updates are refused, fail closed. |
Then run the built-in test, which assumes the role, describes the instance, and lists one page of the recording prefix without touching any contact:
fibric connectors test amazon-connect
Verify contact events are arriving
Place or receive a test call, then tail the event stream. Each contact event arrives as a tenant-scoped envelope; the recording reference resolves to the object in your bucket.
fibric events tail --source amazon-connect
Behind each line is a full envelope, queryable through the Events API. The correlation_id threads all events for a contact together, so a plan proposed off contact.disconnected traces back to the contact.initiated that started the call.
{
"id": "ev_9c44d1",
"object": "event",
"reseller_id": null,
"tenant_id": "t_8f2ac901",
"workspace_id": null,
"source": "amazon-connect",
"event_type": "contact.disconnected",
"correlation_id": "co_7c1f03",
"payload": {
"contact_id": "7c1f…03ba",
"channel": "VOICE",
"queue": "support",
"agent": "r.alvarez",
"duration_seconds": 372
},
"agent_id": null,
"session_id": null,
"received_at": "2026-07-02T15:41:22Z"
}
Confirm idempotent recording pickup
When a recording lands in the bucket, the connector emits recording.available with an s3_uri that resolves to the object in your account. Pickup is idempotent by object key: S3 event notifications are at-least-once, and a re-delivered notification for the same object deduplicates against the recording's key rather than producing a second timeline entry. You can watch this happen by re-driving a notification in your account; the second delivery is receipted as DEDUP and nothing downstream repeats.
This is the same machinery that protects every side-effect in Fibric, the single-flight and idempotency primitives described in Single-flight & idempotency, and the reason a duplicate-notification storm cannot become a duplicate-timeline storm.
Sync call status back to your CX platform
The last step closes the loop: calls.status-sync writes call status onto the customer record in your CX platform of record, so an agent reading a conversation sees the call that just happened beside it. With Kustomer as the platform of record, bind the capability to the cn-kustomer connector:
# call status flows from amazon-connect onto the kustomer customer record
fibric capabilities bind calls.status-sync --connector kustomer
The sync is idempotent: a replayed contact event updates the same timeline entry rather than duplicating it, because the write carries an idempotency key derived from the contact id. It is also a governed write like any other, it routes through the executor, is evaluated against your trust policy, and leaves a receipt. If your policy does not allow it, it does not happen.
The connector can also update contact attributes on a contact, but only within the limits you set: the --attribute-allowlist from step 3 names the attributes it may touch, and an empty allowlist means every attribute write is refused. Fail closed is the default here, as everywhere in governance.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
fibric connectors test fails at assume-role | The trust policy's sts:ExternalId condition does not match the id issued for your workspace, or the principal ARN is wrong. | Re-run fibric connectors add amazon-connect --show-external-id and paste the value into the condition verbatim. |
| Test passes but no events arrive | The contact event stream is not enabled on the instance, or the role is scoped to a different stream than the instance writes to. | Confirm data streaming is enabled in the Connect console and that the stream ARN in the permissions policy matches it. |
recording.available events arrive but the recording cannot be read | The S3 statement is missing the object-level resource, or the recording prefix in the connector config does not match where Connect writes. | Check both the /connect/* resource in the policy and --recording-prefix; they must cover the same keys. |
Status sync receipts show blocked | Your trust policy has no rule allowing calls.status-sync. No matching policy means BLOCK, fail closed. | Add an allow rule for the capability; see Trust tiers. |
| Duplicate timeline entries in the CX platform | Two connector instances are bound to the same Connect instance under different names, so the idempotency keys differ. | Keep one connector instance per Connect instance; remove the duplicate with fibric connectors list and uninstall. |
Next steps
- Connect Kustomer: set up the CX platform side of the status-sync loop.
- Run an ops analyst: put an operator on top of the call events you just connected.
- Monitor your operators: alerts and health signals for the connector and everything downstream.
- The event envelope: the one canonical shape every contact event travels in.
- Tenancy & isolation: how contact events are walled off per tenant from the first row written.