MyAddress ID · implementation guide
Implement MyAddress ID sign-in
MyAddress ID is a standard OpenID Connect provider for server applications. This guide gives a
minimal pattern using openid-client; another standards-compliant server library is
equally suitable.
1. Register the application
Sign in and register an application. Supply a public
homepage and each callback URI, one per line. Keep one callback host per registration. HTTPS is
required in production; HTTP is accepted only for localhost,
127.0.0.1, or [::1] during local development.
Registration returns a client ID and shows the client secret once. MyAddress ID supports server applications: keep both values in server-side configuration in every environment. The localhost callback exception does not change that requirement. Rotating the secret immediately invalidates the previous value.
2. Use the standard authorization-code pattern
Configure from OpenID Connect discovery. Requests use
openid email; both scopes are required and additional scopes are rejected. The
following pattern keeps the provider-specific configuration and the complete browser flow
together.
import * as oidc from 'openid-client';
const issuer = 'https://id.myaddress.cc';
const clientId = process.env.MYADDRESS_OIDC_CLIENT_ID!;
const clientSecret = process.env.MYADDRESS_OIDC_CLIENT_SECRET!;
const config = await oidc.discovery(
new URL(issuer),
clientId,
{
client_secret: clientSecret,
token_endpoint_auth_method: 'client_secret_basic',
id_token_signed_response_alg: 'ES256',
},
oidc.ClientSecretBasic(clientSecret),
);
type PendingSignIn = {
state: string;
nonce: string;
verifier: string;
};
export async function startSignIn(redirectUri: string) {
const state = oidc.randomState();
const nonce = oidc.randomNonce();
const verifier = oidc.randomPKCECodeVerifier();
const challenge = await oidc.calculatePKCECodeChallenge(verifier);
// Save before redirecting; use once at the callback.
const pending: PendingSignIn = { state, nonce, verifier };
const redirectTo = oidc.buildAuthorizationUrl(config, {
response_type: 'code',
redirect_uri: redirectUri,
scope: 'openid email',
state,
nonce,
code_challenge: challenge,
code_challenge_method: 'S256',
});
return { redirectTo, pending };
}
export async function finishSignIn(callbackUrl: URL, pending: PendingSignIn) {
// This one call exchanges the code and validates the ID token.
const tokens = await oidc.authorizationCodeGrant(config, callbackUrl, {
expectedState: pending.state,
expectedNonce: pending.nonce,
pkceCodeVerifier: pending.verifier,
});
const claims = tokens.claims();
// MyAddress claims: { sub: string, email: string, email_verified: true }.
return claims;
}
Store pending before redirecting, then pass the complete callback URL—its query
parameters included—to finishSignIn; do not reconstruct it, because that discards
code, state, and MyAddress's iss parameter. If MyAddress
returns an error, the state does not match, or validation fails, do not create an application
session.
3. Create the local session
finishSignIn returns the verified ID-token data your application needs. Read
claims.sub and claims.email, find or create the local account using
issuer + claims.sub, then create your own application session. Do not use the
short-lived ID token as a browser session.
subject- The pairwise MyAddress identifier for this application connection.
email- The generated MyAddress address for this connection, never the private sign-in address.
email_verified-
trueconfirms that MyAddress has verified the generated address. You may treat it as a verified contact address for this connection; it says nothing about the undisclosed private sign-in address.
Connection and session lifecycle
The person explicitly approves the connection. They can later disable or remove it, after which it cannot complete a new authorization or receive new mail. MyAddress ID does not send back-channel logout requests, so choose an application session duration and reauthentication policy that suits your product.
This profile supports server-side Authorization Code Flow only. It does not issue refresh tokens or support browser-only, native, device, or machine-to-machine clients.
Send messages
See the separate message API guide to send from one of your MyAddress mailboxes to active application connections.
Discovery provides the current endpoints and public signing keys: https://id.myaddress.cc/.well-known/openid-configuration.