Writing a connector
A connector is a folder with a manifest and one class. If your country’s registry answers an HTTP call, this is an afternoon of work, not a fork of the project.
The shape
A connector is a directory under connectors/ containing three things: a manifest declaring what it is, an implementation that talks to the outside world, and a thin adapter implementing the capability’s interface. Nothing else in the codebase needs to know your country exists.
connectors/aadhaar/
connector.json id, country, capability, config keys
aadhaar.py the HTTP client
adapter.py implements IdentityVerificationConnectorThe manifest declares one capability out of the seven, a two-letter country code, and every configuration key the connector reads. That last list is what the panel and the command line use to report the connector as configured or not — key names are shown, values never are.
Six rules
- Read the capability’s interface first; it is the specification. Each one is a handful of methods with a docstring saying what “not configured”, “not found” and “provider unavailable” have to mean. Implement that, nothing wider.
- Fail with the shared errors. Raise the framework’s own “not found” and “provider unavailable”, not a new exception type of your own. Every caller already handles those two, which is what makes your country work without touching their code.
- Ship a test mode. A connector that can only be exercised against a live government endpoint cannot be tested, cannot be demonstrated, and cannot be reviewed. One flag, deterministic answers, no network. Every connector in the repository has one.
- Degrade, never crash. Unconfigured has to leave the product usable, and the pull request has to contain the test that proves it. This is the single rule the reviewer will check hardest.
- Never print a secret. Not in a log line, not in an error message, not in the status screen. Presence or absence is the whole reportable surface.
- One capability per connector. A registry that answers both identity and coverage is two connectors sharing a client, not one connector with a flag.
What a pull request needs
- The manifest, with its identifier equal to the directory name and a capability that actually exists.
- The adapter, delegating to the implementation rather than containing it.
- Three tests: the connector is discovered, the unconfigured case degrades as documented, and the test mode answers.
- A row in the connectors documentation, honest about what is real and what is a stub.
Be honest about wiring
The registry discovers connectors, enables them and holds their configuration. What it does not yet do everywhere is dispatch: several call sites in the Argentine stack still import their connector directly, because that code predates the interface. A new country that wants its identity provider on the login screen today therefore also needs a few lines of glue at the call site, following how Argentina does it.
That is stated here rather than discovered later. Replacing those direct imports with a lookup through the registry is the next slice of work, and a pull request that does it for the capability you care about is welcome.