Transmitters
Overview
This guide connects a Shared Signals Framework (SSF) transmitter to Britive, and sends a test event end to end. The worked example uses caep.dev, a public SSF test transmitter. The same Britive settings apply to any transmitter.
What you’ll accomplish:
- Add the transmitter in Britive and map an event to a Britive action
- Point the transmitter at the Britive event endpoint
- Send a session-revoked event and confirm Britive logged the user out
Before You Begin
- A Britive user who can manage Shared Signals, for example through TenantAdminRole or SecurityAdminRole. See Permissions.
- A Britive user to receive the test event, with at least one active checkout so you can see the check-in
- A transmitter that can deliver events by push (HTTP POST). For the worked example, a caep.dev access token
- For the API steps, a Britive API token for the user who manages Shared Signals
The test event acts on a real user. Use a test user, not your own administrator account.
How It Works
The transmitter sends each event to Britive as a signed Security Event Token (SET). The signed SET is the credential. There is no Authorization header.
sequenceDiagram
participant T as Transmitter
participant B as Britive (/sse/events)
participant U as Britive user
T->>B: POST signed SET (application/secevent+jwt)
B->>T: Fetch signing keys from the issuer's discovery document
B-->>T: 202 Accepted
B->>U: Run the mapped Britive action
Note over B: Result recorded in Shared Signals > Events
Britive validates every SET before acting on it:
| Part | Requirement |
|---|---|
iss | Exactly matches the Issuer URL of a transmitter added in Britive, including any trailing slash |
aud | https://<your-tenant-domain>/sse/events or https://<your-tenant-domain> |
events | Exactly one event, and its URI is mapped to a Britive action for this transmitter |
sub_id | email format, with an email field |
iat, jti | Present |
Header kid | Matches a key in the transmitter’s JWKS |
Britive finds the transmitter’s signing keys from jwks_uri, which it reads from {iss}/.well-known/openid-configuration or, if that is not available, {iss}/.well-known/ssf-configuration. The SET must be signed with RS256, RS384, RS512, ES256, ES384, or ES512.
Britive Actions
Each event you map runs one Britive action on the user. The actions are stacked: each one includes everything the action before it does.
| Action | Checks in the user’s active checkouts | Ends the user’s Britive sessions | Disables the user |
|---|---|---|---|
| Force Checkin | ✓ | ||
| Force Logout | ✓ | ✓ | |
| Disable User | ✓ | ✓ | ✓ |
- Force Checkin ends the user’s privileged access. The user stays signed in and can check out again.
- Force Logout also ends the user’s sessions, so the user must sign in again. It does not revoke the user’s API tokens.
- Disable User also disables the account. The user cannot sign in or use their API tokens until an administrator enables the account again.
For Force Logout and Disable User, Britive runs every part of the action even if an earlier part fails.
After a Force Logout or Disable User, existing sessions can keep working for up to about 60 seconds while caches expire. This is expected.
Recommended mappings:
| Event | Britive action |
|---|---|
Session Revoked (caep/event-type/session-revoked) | Force Logout |
Credential Change (caep/event-type/credential-change) | Force Logout |
Account Disabled (risc/event-type/account-disabled) | Disable User |
Credential Compromise (risc/event-type/credential-compromise) | Force Logout or Disable User |
Confirm the Event Endpoint Is Reachable
Send an empty request to your tenant’s event endpoint. The path is /sse/events, not /ssf/events.
curl -i -X POST https://<your-tenant-domain>/sse/events \
-H "Content-Type: application/secevent+jwt" \
--data "x"A 400 response with Invalid SET format means the request reached the endpoint.
Add the Transmitter in Britive
Use the iss value exactly as it appears in the transmitter’s SETs. caep.dev sends https://ssf.caep.dev/ with a trailing slash. Its discovery document lists the issuer without the slash.
The Issuer URL cannot be changed later. To use a different URL, delete the transmitter and add it again.
Using the Britive Console
Open the Transmitters tab
Click Admin → Security → Shared Signals → Transmitters.
Add the transmitter
Click Add, enter a name and the Issuer URL, then click Save.
Name: caep.dev
Issuer URL: https://ssf.caep.dev/Open the transmitter’s mappings
Click Manage on the transmitter, then click the Mappings tab.
Map an event to a Britive action
Select the event under Event and the Britive action under Action. Click the row’s Add icon, then click Save.
Event: caep-session-revoked
Action: Force LogoutForce Logout checks in all of the user’s active checkouts and ends their Britive sessions. See Britive Actions above. Britive rejects events from a transmitter that has no mappings.
Send a Test Event
Point the transmitter at Britive
In the transmitter, create a push stream that delivers to Britive.
Delivery method: Push (urn:ietf:rfc:8935)
Endpoint URL: https://<your-tenant-domain>/sse/events
Audience: https://<your-tenant-domain>The audience can also be the full endpoint URL. Do not add a trailing slash to either.
Send the event
From the transmitter, send a Session Revoked event with an email subject.
"sub_id": {
"format": "email",
"email": "test.user@example.com"
}Britive matches the email against the user’s email address, username, user ID, or external ID.
Verify
A 202 response from Britive means the event was accepted, not that the action succeeded. Check the result.
- Open Admin → Security → Shared Signals → Events and filter by Received.
- Expand the newest entry. Raw SSF Event shows the user’s email, and Status and Outcome show the result.
- Confirm the user’s checkouts are checked in and the user must sign in again.
Troubleshoot
| Symptom | Cause | Fix |
|---|---|---|
401 | The request went to an /api/... path, which requires Britive authentication | Send events to https://<your-tenant-domain>/sse/events |
403 | Content-Type is not application/secevent+jwt | Set Content-Type: application/secevent+jwt |
404 | The request was not a POST | Send events with POST |
400 Missing SET | The request body is empty | Send the signed SET as the raw request body |
400 Invalid SET format | The body is not a compact JWT | Send the signed SET as the raw request body |
400 Missing issuer or 400 Missing jti claim | The SET has no iss or no jti | Include iss, jti, and iat |
400 No events in SET or 400 Expected exactly one event, found <n> | events is empty or has more than one event | Send one event per SET |
400 Missing sub_id claim or 400 Missing email in sub_id | The SET has no sub_id, or sub_id has no email | Send sub_id in email format with an email value |
400 Unsupported subject format: <format>. Only 'email' is supported | sub_id.format is not email | Configure the transmitter to send email subjects |
400 Untrusted issuer: <iss> | iss does not exactly match an Issuer URL, or the transmitter has no mappings or is disabled | Compare iss in a SET with the Issuer URL, including the trailing slash. Add a mapping. To enable the transmitter, send PATCH /api/ssf/admin/issuers/{issuerId} with {"enabled": true} |
400 Event type not permitted: <event URI> | The event URI is not mapped for this transmitter | Map the event URI to a Britive action |
400 Failed to discover JWKS URI: <reason> | Neither discovery document returns a jwks_uri | Publish jwks_uri at {iss}/.well-known/openid-configuration or {iss}/.well-known/ssf-configuration |
400 Signature validation failed: Audience doesn't match | aud is not one of the accepted values, or has a trailing slash | Use an audience from How It Works |
400 Signature validation failed: The specified alg value is not allowed | The SET is signed with an unsupported algorithm | Sign with RS256, RS384, RS512, ES256, ES384, or ES512 |
400 Signature validation failed: Signature verification failed | The signature does not match the key Britive found | Check that the transmitter signs with a key published in its JWKS |
400 Failed to validate SET signature | Britive could not get a signing key, for example the kid in the SET header is not in the JWKS | Check that the JWKS at jwks_uri contains the signing key |
202, but the event shows as failed | The Britive action did not complete, for example because no Britive user matches the subject email | Check the user’s email address, username, user ID, or external ID in Britive |
| Shared Signals changes are rejected | The user lacks securityadmin.security.manage | See Permissions |
Failed actions are not retried. Send the event again after fixing the cause.
Next Steps
- Map the other events your transmitter sends. See Britive Actions for the recommended mappings.
- Events: review received events and their results