Hi Internet Identity team,
and hi everyone in the community interested in Internet Identity and native client integration.
I’m exploring native app login support for Internet Identity and opened two draft PRs in my fork before preparing an upstream proposal.
The current PRs are in my own fork, but if the design direction looks acceptable, my intent is to reduce this into an upstream-ready change set and send it to the DFINITY Internet Identity repository. Before doing that, I would really appreciate early design feedback, especially from the II team / maintainers.
The goal is to let desktop and mobile apps start authentication in the system browser and receive the result through a registered redirect URI, without requiring a browser bridge.
This is not intended to turn Internet Identity into a generic OIDC provider or to introduce a generic JWT/userinfo-based identity layer. The goal is narrower: use an OIDC/OAuth-compatible authorization request shape where it fits, while keeping IC delegation retrieval as an Internet Computer-specific extension.
Draft PRs:
PR #5 is the initial prototype. PR #6 is stacked on top of it and is the direction I currently think is cleaner, because native apps can open the discovered authorization endpoint directly instead of depending on a custom prepare-style API.
Background
Today, Internet Identity is mainly optimized for browser-based dapp login.
For native desktop/mobile clients, I would like to support a flow where:
-
the native app discovers Internet Identity endpoints from
/.well-known/openid-configuration -
the app opens the system browser
-
the user authenticates with Internet Identity
-
Internet Identity redirects back to the native app
-
the native app exchanges the authorization result for an IC delegation
The design uses standard OIDC/OAuth concepts where they fit, but keeps IC-specific delegation retrieval separate from generic OIDC token issuance.
PR #5: native app redirect login flow
PR #5 adds the first version of the native app redirect flow.
Main points:
-
adds native authorization preparation, completion, token exchange, and delegation exchange support
-
exposes
authorization_endpoint,token_endpoint, andic_delegation_endpointin discovery metadata -
supports RFC 8252-style loopback redirects, allowing desktop apps to use an ephemeral local port
-
adds
/oauth2/tokenand/oauth2/delegation -
keeps
/oauth2/delegationseparate because the signed delegation response needs query-call certificate context -
adds frontend helper APIs, generated bindings, integration tests, frontend tests, and docs
In this version, native apps first call a prepare-style API before opening the browser.
PR #6: OIDC-style authorization request variant
PR #6 is stacked on top of PR #5 and changes the browser entrypoint to be closer to a standard OIDC authorization-code request.
Instead of exposing a public prepare_native_authorization flow to native apps, native apps open the discovered authorization_endpoint directly with parameters such as:
-
response_type=code -
client_id -
redirect_uri -
scope -
state -
nonce -
code_challenge -
code_challenge_method=S256
It also adds IC-specific extension parameters:
-
ic_origin -
ic_session_public_key -
optional
ic_max_time_to_live
Native apps still use the same two-step delegation retrieval flow:
-
/oauth2/token -
/oauth2/delegation
My current feeling is that PR #6 may be the cleaner direction because it reduces the custom native-app preparation contract and makes the authorization request easier to understand for clients familiar with OIDC/OAuth.
Security notes / intended invariants
The intended security model is:
-
native clients are treated as public clients; no shared client secret is assumed
-
authorization code flow uses PKCE, with
S256required -
authorization codes are short-lived and single-use
-
token exchange is bound to the original request, including
client_id,redirect_uri,code_verifier, and the IC-specific authorization parameters -
redirect URI matching is exact, except for the RFC 8252 loopback-port exception
-
loopback redirects should use loopback IP literals such as
127.0.0.1or[::1] -
stateandnonceremain client-managed anti-CSRF / replay protections -
the final IC delegation remains bounded by II’s existing delegation lifetime rules
I would especially appreciate review of whether these are the right invariants for this flow, and whether there are any II-specific security concerns I am missing.
Feedback requested
I’m mainly looking for early design feedback before reducing this into an upstream-ready change set.
In particular:
-
Should PR #6’s OIDC-style authorization request be the preferred direction over the prepare-style flow in PR #5?
-
Is exposing
ic_delegation_endpointas an IC-specific discovery metadata extension acceptable? -
Is the two-step
/oauth2/token→/oauth2/delegationflow the right shape, given the certificate/query-call context needed for signed delegation retrieval? -
Are the IC-specific authorization parameters named and scoped appropriately?
Examples:ic_origin,ic_session_public_key,ic_max_time_to_live -
Does RFC 8252-style loopback redirect handling make sense for II native clients?
-
Are there security concerns around redirect URI validation, PKCE/code binding, replay prevention, token reuse, or delegation retrieval?
-
Would maintainers prefer this as one PR, or split into smaller PRs?
Thanks. I would appreciate early design feedback, especially from the DFINITY II team / maintainers, on whether the PR #6 direction is an appropriate shape for upstream before I reduce this into an upstream-ready change set.
