Skip to main content

EidKit SSO Integration

EidKit SSO is a standard OIDC identity provider. You integrate it exactly like Google Sign-In or Apple Sign-In — a Client ID, a Client Secret, a redirect URI.

Getting credentials

Credentials are issued instantly via the Developer Portal — no forms, no email.

What you need:

  • A Romanian electronic identity card (CEI) with NFC chip
  • The EidKit app installed on your phone

Steps:

  1. Go to dashboard.eidkit.ro
  2. Click "Înregistrează aplicația cu buletinul electronic"
  3. Scan the QR code with the EidKit app and tap your card
  4. Copy your client_id and client_secret — the secret is shown only once
Electronic ID card required

CEI authentication is required both to register in the portal and to test your integration. If you don't have an electronic ID card yet, contact hello@eidkit.ro.

What you get

  • Client ID and Client Secret — generated instantly
  • Issuer URL: https://idp.eidkit.ro
  • OIDC autodiscovery at https://idp.eidkit.ro/.well-known/openid-configuration
  • Cryptographically verified data from MAI — not self-reported by the user

Available scopes

ScopeData returned
openidsub — stable pseudonym (SHA-256 of CNP, not the raw CNP)
profilename, given_name, family_name, birthdate
addressaddress.formatted — MAI-verified address, not self-declared
cei:documentNumber, series, expiry date, issuing authority
cei:cnpCNP extracted server-side from verified DG1 — not from the app payload
cei:pictureFace photo (JPEG base64, ~33KB)
cei:signatureHandwritten signature image (JPEG base64, ~3.5KB)

Most clients only need openid profile. Images are opt-in for specific use cases (e.g. insurance, HR).


Registration and login — the same flow

There is no difference between login and registration. The sub in the JWT is a stable, unique pseudonym per person. The first card tap creates the account automatically.

const { sub, name, given_name, family_name, address } = jwtPayload;

let user = await db.users.findOne({ eidkitSub: sub });

if (!user) {
// First authentication = automatic registration
user = await db.users.create({
eidkitSub: sub,
name: name,
givenName: given_name,
familyName: family_name,
address: address?.formatted,
createdAt: new Date(),
});
}

// Subsequent authentications = login with the same sub
await session.create({ userId: user.id });

JWT verification without network calls

After initial setup, token signatures can be verified locally using the public JWKS — no call to EidKit per request:

GET https://idp.eidkit.ro/.well-known/jwks.json

Cache the public keys and verify the JWT signature locally on every request.


Example JWT — typical scopes (openid profile address)

{
"sub": "a3f7bc9d...",
"name": "CĂTĂLIN TOMA",
"given_name": "CĂTĂLIN",
"family_name": "TOMA",
"birthdate": "1985-03-15",
"address": {
"formatted": "Str. Exemplu Nr. 1, Timișoara, Timiș"
},
"iss": "https://idp.eidkit.ro",
"aud": "your-client-id"
}

Session management

EidKit issues an ID token once — there are no refresh tokens in the standard configuration. You manage the user session with your own cookie or server-side session. If you need re-verification (high-security flows), the user taps their card again.

Tokens

Use the ID token — it contains everything you need. The access token has no EidKit API to use it against.


Security guarantees

Unlike a traditional OIDC provider that issues tokens on the basis of a password, EidKit SSO will not issue any token unless all of the following verifications pass:

CheckWhat it proves
DSC chain → MAI CSCAThe identity card was issued by the Romanian state
DG1 hash from SODThe identity data (including CNP) has not been modified since MAI signed it
DG14 hash from SODThe chip's public key (Q_chip) was signed by MAI — cannot be substituted
Chip ECDSA signatureThe physical card was present — cannot be forged without the chip
Server-side challengeThe signature is fresh — cannot be replayed
CE81 chain → MAI GenPKI Sub-CAThe chip's authentication key was issued by MAI
CA binding (ECDH, BSI TR-03110)The chip that signed CE81 holds exactly the Q_chip key from the identity — split-proof attack is impossible

PIN proof: Active Authentication on the CEI chip requires verification of the 4-digit auth PIN before CE81 can sign the challenge. A valid AA signature implies the user knows the PIN of the physical card.

The server extracts the CNP directly from verified DG1 bytes — it does not accept the CNP from the app payload.