Lifecycle & decisions rapidvalue.eu →

External onboarding

Externals are the population most likely to arrive through a side door. A supplier's engineer is needed by Monday; the partner has their own administrator who knows their own people; a roster arrives as a spreadsheet, or as a feed from a system nobody in your organisation controls. Each is a reasonable request, and each is a route by which someone can end up holding access no control ever looked at.

This page is about how those routes are closed. The claim it has to defend is narrow and absolute: no intake path grants access, and no intake path can activate anyone.

The gate is in the access calculation, not the interface

An external taken on here gets a real identity record immediately — they exist, they are searchable, their sponsor can see them, their onboarding can be worked on — with the status gated.

A gated identity holds no expected access at all. Not "none provisioned yet"; none expected. The access calculation short-circuits on the status before it reads a single policy, role or request, and returns an empty expected set with a warning saying why. Reconciliation then treats that empty set as it treats any other: nothing is provisioned, and anything that somehow exists in a target system is drift to be removed. A policy that would have matched this person perfectly does not fire, because the calculation never reaches it.

That placement is the whole design. A gate enforced in the interface is a suggestion: it holds for as long as every caller goes through the screen that hides the button — and then someone writes an integration, or a sweep runs, or a synchronisation ticks, and the control was never really there. Putting the lock in the calculation every provisioning decision descends from means the gate does not depend on anyone's good intentions, including ours.

The lock is deliberately not applied to pending_hire — the joiner pre-provisioning status, where an employee's accounts are prepared before their start date on purpose. Folding the two together would have been tidier and wrong: one means "prepare this person's access early", the other "this person has no access until somebody says so".

One activation act

Clearing the gates does not activate anyone. Activation is a separate, explicit call, restricted to administrators, and it is the only thing in the platform that moves an identity out of gated. No sweep does it, no import does it, and the intake routes below do not do it.

It refuses while any required gate is unpassed, and the refusal names the outstanding gates rather than saying "not allowed". A gate is cleared by passing it or by waiving it; waiving demands a written reason, is restricted to administrators or to a role the gate itself names, and lands as a warning-level audit event with that reason attached. An escape hatch that is attributable and reasoned is a control; a silent one is not.

When activation succeeds the identity moves to active through the ordinary lifecycle transition and reconciliation grants the access — birthright policies and roles apply from that moment exactly as for anyone else. There is no parallel granting path inside onboarding, for the same reason single-emitter discipline matters elsewhere: a second route to access is a second place for every downstream gate to be forgotten.

Rejection is the other terminal outcome: a reason is required, the identity is terminated, open gate tasks are withdrawn from their reviewers' inboxes. Cases that simply go quiet do not sit gated forever — a sweep expires those stuck before activation past a configurable window, 90 days by default.

Six ways in, one place they all land

Route What it is
Sponsor form An internal host registers a guest or contractor they sponsor
Contract-management form The same, worked by a central team rather than the host
Self-service invite A signed single-use link the invitee fills in themselves
Delegated partner admin The partner's own administrator, scoped to their organisation
Bulk CSV A roster imported as a file, one case per row
Partner feed The partner's HR or roster system, connected as an ordinary source

Every one produces the same thing: a gated identity and an open case. They differ in who does the typing and where the data comes from, not in what they yield, because they converge on the same two internal steps — create the case, then open its gates. Bulk import runs every row through the same intake call an individual form uses; the partner-feed bridge wraps a case around an identity the synchronisation just created. Neither has a shortened version of its own. Bulk import is otherwise deliberately unremarkable: size and row ceilings, a preview and a validate pass that create nothing, per-row isolation so one bad row cannot take its batch with it, and rows whose email already exists skipped rather than duplicated — a corrected file is safe to re-run.

The partner feed is a source, not an authority

A partner's roster system connects as a normal connector. What makes it an intake route is a binding: an external organisation names it as its feed, and the governing profile says its intake model is a partner feed. After that connector synchronises, a bridge runs over the delta. Four properties are load-bearing.

A joiner is gated first, before anything else. The bridge sets the status lock as its first write, then binds the organisation, strips the record and opens the case. If the case fails to open, the person is left gated with a loud log entry for an administrator to pick up. The order is chosen so every failure mode leaves someone without access rather than with it.

A synchronisation can never activate a gated identity. The sync engine's own field-change logic refuses that specific transition. Without it, a feed reporting a freshly gated joiner as "enabled" would flip them active on the next tick — a gate bypass arriving not through anyone's decision but through the scheduler. A feed reporting someone as disabled still terminates them: the fail-safe direction stays open.

The tenant's own dates win. A person's end date and the sweep enforcing it run regardless of what the partner reports. Externals have no HR department of yours to leaver them, so that sweep is the leaver path: past the end date and its configured grace the identity is terminated and reconciliation removes the access. Sponsors are warned beforehand at configurable horizons — two weeks and one week by default — and renewing the engagement extends the organisation's contract end date and every person's end date together.

A re-listed leaver is re-gated, not restored. Someone the feed drops and later lists again gets a fresh case and a fresh checklist rather than silently regaining what they had.

A failure in this bridge is a genuine synchronisation error, not a best-effort step that logs and moves on. A quietly skipped bridge would leave feed joiners active — precisely the condition it exists to prevent.

Invite tokens

The self-service route mints a signed token bound to one organisation, one profile and one pre-created case.

It carries no personal data — identifiers, an audience, a lifetime and a unique token id; no name, no email address. Who was invited lives server-side in a row keyed by that id, so a token in a mail archive, a proxy log or a screenshot discloses nothing about its subject. It is single-use, riding the same revoked-token mechanism as account activation and password reset alongside a consumed-at marker that makes the state visible to the sponsor; consumption and submission commit together, so a form rejected for a bad value does not burn the link. It is short-lived — seven days by default, thirty at most — and minting is rate limited per email address, so an invite cannot be quietly re-issued indefinitely. And the invited address wins: whatever email the form supplies is overwritten with the address the invite was issued to, so a token holder cannot enrol somebody else, or themselves under a different identity.

The error contract is deliberately blunt. Anything that was never a valid invite — a made-up token, a tampered one, a signature that does not verify, an unknown token id — returns the same 404 with the same wording. A token that was real and has lapsed, been used, or arrives at a case that has moved on returns 410. Excessive requests return 429.

Collapsing four distinct failures into one 404 avoids an oracle: were "no such invite" and "invite exists, but you got the signature wrong" distinguishable, the endpoint would confirm to anyone willing to guess that a named person is being onboarded. The 410 is not a leak of the same kind — producing a signature-valid token requires having held a real one, so somebody who never had an invite sees 404 and nothing else. These endpoints are unauthenticated by necessity, the invitee having no account yet, so the token is the authorisation, with the mint limit, a per-source limit on the public endpoints and the token's own unguessability underneath it.

Delegated org admins

A partner's own administrator can be given the ability to onboard their own people. The role is bounded on two independent axes, and both are checked.

What they may do is a capability list — create and update an identity; create, read and submit an onboarding case; raise an access request. Nothing else. A capability the role does not name is refused even inside their own organisation.

Whose records they may touch is a scope: the external organisations bound to them. The check requires the target to carry the scope attribute and for its value to be one they hold. A missing attribute is out of scope; an empty scope set is out of scope for everything. Both defaults fail closed, which is the right direction for a role held by somebody outside your organisation. Listing endpoints apply the same scope, so a delegated administrator's view of cases, organisations and people contains only their own — this is not a tidiness filter over an unbounded query.

Designating a delegated administrator provisions them a login and records a warning-level audit event; revoking their last organisation binding deactivates it again. The separate carve-out letting an internal host create a case they sponsor themselves is restricted to active employees and contractors — explicitly not to external people — so it cannot be used to escape a delegated scope. Sponsorship is recorded through the ordinary ownership model rather than as a field on the case, so an in-flight case whose sponsor leaves is caught by the same owner-handover machinery as anything else with an owner.

What may be collected, and for how long

A data-requirement set is one list of fields, and it is the allow-list for every intake route. The set bound to the external organisation wins over the one on the profile; with neither, a conservative built-in list applies. First name, last name and email are always present and always required — an identity cannot exist without them.

On the human routes a field outside the set is refused, not silently dropped: a caller pushing extra personal data hears about it, because dropping it quietly would let an integration send more than agreed for months without anyone noticing. On the feed route the same boundary is enforced by stripping — a partner's system cannot be argued with mid-request, so out-of-set columns are nulled and out-of-set attributes removed as the record crosses into the estate. The bulk importer reports which of the file's columns it is dropping before you commit.

Retention is expressed per field on the same set, so data ages out without a separate erasure project. Each field declares when its window ends: at contract end, a fixed number of days after intake, or a number of days after activation. A sweep erases what is due, records that it did, and skips it thereafter. Three things are deliberate: the erasure marker makes the sweep idempotent; the audit record names the keys erased and never their values; and the core three fields plus the contract end date are never field-erased, being the identity and its governing date. Wholesale erasure of a person remains the separate data-protection path, with audit content retained through it on the usual legal basis. Documents uploaded as gate evidence have their bytes erased on the same schedule, while the record that they existed survives.

Known edges, published rather than discovered


Further reading: