Building a connector
For developers
CardOffice is the people and credential layer; access control, directory, roll and wallet systems connect to it. Every connector is described the same way, so an administrator sees them all on one page under Settings, Connectors, with what each owns and whether it is working, and a partner’s module slots in beside Gallagher Command Centre without special treatment.
The contract
Section titled “The contract”A connector is a definition and an adapter.
The definition says what it is: a key (gallagher-command-centre), a name
and vendor, a kind (access_control, directory, roll_feed or
credential_wallet), a direction (push, pull or both), the
capabilities it implements (people, status, photos, cards,
access_groups, pins, mobile_credentials, drift_report, health),
a semantic version, and which side owns each field: name, department,
status, photo, card numbers and access groups, each cardoffice,
connector or either. One owner per field is what keeps two systems
from fighting over a record; the audit log records every write either way.
The adapter answers for it:
| Operation | Required | What it does |
|---|---|---|
describe() |
yes | Returns the definition. |
instances(organisationId) |
yes | The configured connections for one organisation, never another’s. |
health(instance) |
yes | One of healthy, degraded, down, off, not_configured, with the last success, the last error, a backlog where it can count one, whether its agent is online, and a sentence a person can read. |
pushPerson(instance, person) |
if it pushes | Idempotent: the same person twice is one record on the far side. Returns created, updated, unchanged or skipped and the far side’s reference. |
pull(instance) |
if it pulls | Reads the far side’s changes and applies them under the field ownership declared. Returns seen, created, updated, deactivated and missing. |
drift(instance) |
if declared | Compares both sides person by person and changes neither. |
trigger(instance) |
optional | Starts the next run now. |
The types live in the CardOffice repository at
packages/core/src/connectors/contract.ts. The shortest complete adapter is
the reference connector beside it, fixture.ts: an in-memory access
control system that does everything the contract asks.
The conformance suite
Section titled “The conformance suite”runConformance(adapter, fixture) drives an adapter through the contract
with two throwaway organisations and reports a sentence per check:
- the definition meets the contract;
- declared capabilities match the operations implemented;
- instances are listed only for the organisation asked for;
- health reports a contract state and a readable sentence;
- pushing the same person twice is one record on the far side;
- a deactivated person is changed on the far side, and again changes nothing;
- error messages carry no name or ID number;
- a failure shows in health;
- pull reports whole-number counts;
- a drift report changes neither side.
CardOffice runs the suite in its own tests against the reference connector and against deliberately broken copies (one that duplicates on push, one that names people in errors, one that ignores status, one that lists other tenants, one that invents a health state), so the suite is known to catch what it claims to.
Certification
Section titled “Certification”A connector is certified when the suite passes and the checklist in the
repository’s docs/connector-certification.md holds: one owner per field
documented, idempotent push, status honoured, no personal data in errors or
logs, honest health, runs recorded, tenant isolation with encrypted
credentials, bounded calls with backoff, a semantic version with announced
breaking changes, and a set-up page. Certified connectors are listed here.
| Connector | Kind | Direction | Status |
|---|---|---|---|
| Gallagher Command Centre | Access control | Both | Built in |
| SCIM provisioning (Entra ID and any SCIM 2.0 client) | Directory | Push | Built in |
| Google Workspace directory | Directory | Pull | Built in |
| Roll feed (the sync agent or the REST feeds) | Roll feed | Push | Built in |
Getting started
Section titled “Getting started”Ask support for a sandbox organisation on the development instance; it comes with synthetic people and a Command Centre fixture. Build the adapter against the contract, run the suite, and send the report.
© 2026 Secure ID Ltd. All rights reserved.Documentation licence and terms