DEV Community

Ivan Rossouw
Ivan Rossouw

Posted on AI-assisted

Don’t Turn Delegated Access Into an Identity Oracle

Delegated access often starts with an innocent mismatch.

A person knows an email address. The authorization system knows an account identifier. The obvious bridge is a search box: enter the address, find the account, then grant access.

That bridge can become a privacy leak.

If the screen behaves differently for a known address and an unknown one, every attempt answers a sensitive question: “Does this person have an account here?” An authenticated caller can repeat that question across many addresses. The feature may be correctly authorized for its intended task while still exposing more identity information than the task requires.

The deeper lesson is simple: account discovery is not a necessary prerequisite for delegated access. Identity can be resolved later, at the moment the recipient proves ownership and gives consent.

The convenient design carries a hidden query

Consider a generic workflow in which one person wants to share a limited capability with another.

The direct version usually looks like this:

  1. Enter the recipient’s address.
  2. Search for a matching account.
  3. Show whether a match exists.
  4. Create access against that account.

Authorization to share the resource does not make the lookup harmless. Even subtle differences disclose the answer: different text, a disabled button, a profile preview, an HTTP status, or noticeably different timing.

This is a useful design-review question: what does the caller need to accomplish, and what does the interface reveal merely because it is convenient?

Move identity resolution to acceptance

An invitation workflow changes the order of proof.

The initiator provides an address and the intended scope. The system records an invitation and returns the same public outcome whether the address currently belongs to an account or not. Nothing attempts to answer the account-existence question.

Most importantly, the invitation itself grants no access.

When the recipient follows the invitation, they authenticate. The system compares the account’s confirmed address with the invited address. Only a match may inspect the offer and accept it. The access record is then created against the identity that actually accepted.

That ordering gives the workflow better semantics:

  • the initiator names a person in a form they genuinely know;
  • the system does not reveal whether an account already exists;
  • possession of a link is insufficient on its own;
  • the recipient proves control of the invited address;
  • access records consent rather than an assumption made by the initiator.

A token is necessary, but not sufficient

Invitation links are bearer secrets, so their handling deserves the same care as password-reset links.

Persist a one-way hash rather than the raw token. Submit the token in a request body when practical so routine URL logging does not repeat it across server, proxy, and browser records.

Bind the token to the intended identity as well. A forwarded or screenshotted link should not be enough to inspect the offer. Requiring a signed-in account with the matching confirmed address contains that failure mode.

Resending needs a clear contract: mint a new token and invalidate the old one. Otherwise each resend increases the live secrets while the interface still shows one invitation.

Finally, build the link from trusted server configuration. Request-controlled host information should not decide where a live token is sent.

Retry safety belongs in the workflow

Mobile networks fail at awkward boundaries. The server may commit an invitation and send the message while the response never reaches the device.

If pressing the button again creates a fresh invitation, one uncertain response can produce two live tokens. The interface may show only one of them.

A stable command identity lets the server recognize a replay and return the original result without sending again. That identity must describe the request as well as the button press: reusing it with different arguments should be rejected, not silently mapped to an unrelated result.

Delivery outcomes need honest language. A definite rejection differs from an unknown result after handoff. “Unknown” is safer than encouraging a duplicate.

Make consent and access one atomic transition

Acceptance changes two facts: the invitation is consumed, and access is created.

Persist those facts together.

If access is written but the invitation remains pending, the token may be accepted again. That can create a second grant that nobody sees. Revoking the visible grant would leave the duplicate active.

One transaction makes the invariant explicit: there is no state in which acceptance succeeded while the invitation is still redeemable.

Re-check the initiator’s authority inside this transition too. Authority can change between invitation and acceptance. An invitation should not outlive the permission that allowed it to be created.

Test the negative space

The most valuable tests are not only happy-path checks. They prove what the workflow refuses to reveal or create:

  • known and unknown addresses produce indistinguishable initiator results;
  • an invitation alone authorizes nothing;
  • a different or unconfirmed account cannot inspect or accept it;
  • retrying does not send again;
  • resending invalidates the previous token;
  • stale initiator authority blocks new access;
  • repeated acceptance does not create duplicate grants;
  • consumption and access creation succeed or fail together.

The trade-off is deliberate complexity

This design adds states, expiry, delivery handling, retry receipts, token rotation, concurrency, and tests. It is unquestionably more work than a directory lookup followed by an insert.

The added complexity corresponds to uncertainty the simpler design hides. The invitation makes privacy, consent, identity proof, and atomicity explicit.

The practical takeaway is to inspect every workflow that translates a human-readable identifier into an account. Ask whether the caller truly needs account discovery, or whether identity can be resolved by the recipient at acceptance.

Often, the safer flow is also the more truthful one.

Top comments (0)