From 48f753db5f059dcf3f6e1b4682fa099730d9ee88 Mon Sep 17 00:00:00 2001 From: nmoskaleva Date: Mon, 30 Mar 2026 16:22:36 +0200 Subject: [PATCH 1/4] Move tech and eID logos to `components` folder Verify integration cards will be shown on both Homepage and Getting Started page, so I'm moving them accordingly. --- src/Homepage/SignaturesIntegrationCards.tsx | 8 +-- src/Homepage/eIDCards.tsx | 18 +++--- .../VerifyIntegrationCards.tsx | 61 ++++++++++++------ src/{Homepage => images}/logos/eids/freja.svg | 0 src/{Homepage => images}/logos/eids/ftn.svg | 0 src/{Homepage => images}/logos/eids/idin.svg | 0 .../logos/eids/mitid-erhverv.svg | 0 src/{Homepage => images}/logos/eids/mitid.svg | 0 .../logos/eids/no-bankid.svg | 0 .../logos/eids/personalausweis.svg | 0 .../logos/eids/se-bankid.svg | 0 src/{Homepage => images}/logos/eids/vipps.svg | 0 .../logos/integrations/auth0.svg | 0 .../logos/integrations/aws-cognito.svg | 0 .../logos/integrations/csharp.svg | 0 .../logos/integrations/dotnet.svg | 0 .../logos/integrations/expo.svg | 0 .../logos/integrations/firebase.svg | 0 .../logos/integrations/javascript.svg | 0 .../logos/integrations/kotlin.svg | 0 .../logos/integrations/nodejs.svg | 0 .../logos/integrations/okta.svg | 0 .../logos/integrations/onelogin.svg | 0 .../logos/integrations/php.png | Bin .../logos/integrations/php.svg | 0 .../logos/integrations/ping-identity.svg | 0 .../logos/integrations/python.svg | 0 .../logos/integrations/react.svg | 0 .../logos/integrations/swift.svg | 0 .../logos/integrations/vuejs.svg | 0 .../logos/integrations/wordpress.svg | 0 src/pages/index.mdx | 2 +- 32 files changed, 56 insertions(+), 33 deletions(-) rename src/{Homepage => components}/VerifyIntegrationCards.tsx (54%) rename src/{Homepage => images}/logos/eids/freja.svg (100%) rename src/{Homepage => images}/logos/eids/ftn.svg (100%) rename src/{Homepage => images}/logos/eids/idin.svg (100%) rename src/{Homepage => images}/logos/eids/mitid-erhverv.svg (100%) rename src/{Homepage => images}/logos/eids/mitid.svg (100%) rename src/{Homepage => images}/logos/eids/no-bankid.svg (100%) rename src/{Homepage => images}/logos/eids/personalausweis.svg (100%) rename src/{Homepage => images}/logos/eids/se-bankid.svg (100%) rename src/{Homepage => images}/logos/eids/vipps.svg (100%) rename src/{Homepage => images}/logos/integrations/auth0.svg (100%) rename src/{Homepage => images}/logos/integrations/aws-cognito.svg (100%) rename src/{Homepage => images}/logos/integrations/csharp.svg (100%) rename src/{Homepage => images}/logos/integrations/dotnet.svg (100%) rename src/{Homepage => images}/logos/integrations/expo.svg (100%) rename src/{Homepage => images}/logos/integrations/firebase.svg (100%) rename src/{Homepage => images}/logos/integrations/javascript.svg (100%) rename src/{Homepage => images}/logos/integrations/kotlin.svg (100%) rename src/{Homepage => images}/logos/integrations/nodejs.svg (100%) rename src/{Homepage => images}/logos/integrations/okta.svg (100%) rename src/{Homepage => images}/logos/integrations/onelogin.svg (100%) rename src/{Homepage => images}/logos/integrations/php.png (100%) rename src/{Homepage => images}/logos/integrations/php.svg (100%) rename src/{Homepage => images}/logos/integrations/ping-identity.svg (100%) rename src/{Homepage => images}/logos/integrations/python.svg (100%) rename src/{Homepage => images}/logos/integrations/react.svg (100%) rename src/{Homepage => images}/logos/integrations/swift.svg (100%) rename src/{Homepage => images}/logos/integrations/vuejs.svg (100%) rename src/{Homepage => images}/logos/integrations/wordpress.svg (100%) diff --git a/src/Homepage/SignaturesIntegrationCards.tsx b/src/Homepage/SignaturesIntegrationCards.tsx index 5b89fe7f..8c3c94f3 100644 --- a/src/Homepage/SignaturesIntegrationCards.tsx +++ b/src/Homepage/SignaturesIntegrationCards.tsx @@ -1,9 +1,9 @@ import React, { ReactElement } from 'react'; import { LogoCard } from '../components/LogoCard/LogoCard'; -import PythonLogo from './logos/integrations/python.svg'; -import NodejsLogo from './logos/integrations/nodejs.svg'; -import PhpLogo from './logos/integrations/php.svg'; -import CsharpLogo from './logos/integrations/csharp.svg'; +import PythonLogo from '../images/logos/integrations/python.svg'; +import NodejsLogo from '../images/logos/integrations/nodejs.svg'; +import PhpLogo from '../images/logos/integrations/php.svg'; +import CsharpLogo from '../images/logos/integrations/csharp.svg'; const guides = [ { diff --git a/src/Homepage/eIDCards.tsx b/src/Homepage/eIDCards.tsx index c052c15d..3ebf6913 100644 --- a/src/Homepage/eIDCards.tsx +++ b/src/Homepage/eIDCards.tsx @@ -1,14 +1,14 @@ import React, { ReactElement } from 'react'; import { LogoCard } from '../components/LogoCard/LogoCard'; -import MitIDLogo from './logos/eids/mitid.svg'; -import NoBankIDLogo from './logos/eids/no-bankid.svg'; -import SeBankIDLogo from './logos/eids/se-bankid.svg'; -import FtnLogo from './logos/eids/ftn.svg'; -import FrejaIDLogo from './logos/eids/freja.svg'; -import VippsLogo from './logos/eids/vipps.svg'; -import iDinLogo from './logos/eids/idin.svg'; -import MitIDErhvervLogo from './logos/eids/mitid-erhverv.svg'; -import PersonalausweisLogo from './logos/eids/personalausweis.svg'; +import MitIDLogo from '../images/logos/eids/mitid.svg'; +import NoBankIDLogo from '../images/logos/eids/no-bankid.svg'; +import SeBankIDLogo from '../images/logos/eids/se-bankid.svg'; +import FtnLogo from '../images/logos/eids/ftn.svg'; +import FrejaIDLogo from '../images/logos/eids/freja.svg'; +import VippsLogo from '../images/logos/eids/vipps.svg'; +import iDinLogo from '../images/logos/eids/idin.svg'; +import MitIDErhvervLogo from '../images/logos/eids/mitid-erhverv.svg'; +import PersonalausweisLogo from '../images/logos/eids/personalausweis.svg'; const eids = [ { diff --git a/src/Homepage/VerifyIntegrationCards.tsx b/src/components/VerifyIntegrationCards.tsx similarity index 54% rename from src/Homepage/VerifyIntegrationCards.tsx rename to src/components/VerifyIntegrationCards.tsx index ef4f7714..55d2923c 100644 --- a/src/Homepage/VerifyIntegrationCards.tsx +++ b/src/components/VerifyIntegrationCards.tsx @@ -1,116 +1,134 @@ import React, { ReactElement } from 'react'; -import { LogoCard } from '../components/LogoCard/LogoCard'; +import { LogoCard } from './LogoCard/LogoCard'; -import Auth0Logo from './logos/integrations/auth0.svg'; -import JavaScriptLogo from './logos/integrations/javascript.svg'; -import ReactLogo from './logos/integrations/react.svg'; -import NodejsLogo from './logos/integrations/nodejs.svg'; -import VuejsLogo from './logos/integrations/vuejs.svg'; -import ExpoLogo from './logos/integrations/expo.svg'; -import WordpressLogo from './logos/integrations/wordpress.svg'; -import AwsCognitoLogo from './logos/integrations/aws-cognito.svg'; -import FirebaseLogo from './logos/integrations/firebase.svg'; -import OktaLogo from './logos/integrations/okta.svg'; -import PingFederateLogo from './logos/integrations/ping-identity.svg'; -import PhpLogo from './logos/integrations/php.svg'; -import DotnetLogo from './logos/integrations/dotnet.svg'; -import OneLoginLogo from './logos/integrations/onelogin.svg'; -import KotlinLogo from './logos/integrations/kotlin.svg'; -import SwiftLogo from './logos/integrations/swift.svg'; +import Auth0Logo from '../images/logos/integrations/auth0.svg'; +import JavaScriptLogo from '../images/logos/integrations/javascript.svg'; +import ReactLogo from '../images/logos/integrations/react.svg'; +import NodejsLogo from '../images/logos/integrations/nodejs.svg'; +import VuejsLogo from '../images/logos/integrations/vuejs.svg'; +import ExpoLogo from '../images/logos/integrations/expo.svg'; +import WordpressLogo from '../images/logos/integrations/wordpress.svg'; +import AwsCognitoLogo from '../images/logos/integrations/aws-cognito.svg'; +import FirebaseLogo from '../images/logos/integrations/firebase.svg'; +import OktaLogo from '../images/logos/integrations/okta.svg'; +import PingFederateLogo from '../images/logos/integrations/ping-identity.svg'; +import PhpLogo from '../images/logos/integrations/php.svg'; +import DotnetLogo from '../images/logos/integrations/dotnet.svg'; +import OneLoginLogo from '../images/logos/integrations/onelogin.svg'; +import KotlinLogo from '../images/logos/integrations/kotlin.svg'; +import SwiftLogo from '../images/logos/integrations/swift.svg'; const guides = [ { href: 'react', header: 'React', logo: { src: ReactLogo, width: 46, alt: 'React logo' }, + category: 'SPA/Native', }, { href: 'javascript', header: 'JavaScript', logo: { src: JavaScriptLogo, alt: 'JavaScript logo' }, + category: 'SPA/Native', }, { href: 'nodejs-express', header: 'Node.js (Express)', logo: { src: NodejsLogo, width: 70, height: 42, alt: 'Node.js (Express) logo' }, + category: 'Web', }, { href: 'vuejs', header: 'Vue.js', logo: { src: VuejsLogo, height: 46, alt: 'Vue.js logo' }, + category: 'SPA/Native', }, { href: 'kotlin', header: 'Kotlin (Android)', logo: { src: KotlinLogo, alt: 'Kotlin logo' }, + category: 'SPA/Native', }, { href: 'react-native-expo', header: 'Expo (React Native)', logo: { src: ExpoLogo, height: 42, width: 38, alt: 'Expo logo' }, + category: 'SPA/Native', }, { href: 'swift', header: 'Swift (iOS)', logo: { src: SwiftLogo, alt: 'Swift logo' }, + category: 'SPA/Native', }, { href: 'wordpress', header: 'Wordpress', logo: { src: WordpressLogo, width: 42, height: 42, alt: 'Wordpress logo' }, + category: 'Web', }, { href: 'auth0', header: 'Auth0', logo: { src: Auth0Logo, height: 36, alt: 'Auth0 logo' }, + category: 'CIAM', }, { href: 'aws-cognito', header: 'AWS Cognito', logo: { src: AwsCognitoLogo, width: 38, height: 44, alt: 'AWS Cognito logo' }, + category: 'CIAM', }, { href: 'firebase', header: 'Firebase', logo: { src: FirebaseLogo, width: 32, height: 44, alt: 'Firebase logo' }, + category: 'CIAM', }, { href: 'okta', header: 'Okta', logo: { src: OktaLogo, width: 69, height: 23, alt: 'Okta logo' }, + category: 'CIAM', }, { href: 'onelogin', header: 'OneLogin', logo: { src: OneLoginLogo, width: 42, height: 42, alt: 'OneLogin logo' }, + category: 'CIAM', }, { href: 'pingfederate', header: 'PingFederate', logo: { src: PingFederateLogo, alt: 'PingFederate logo' }, + category: 'CIAM', }, { href: 'PHP', header: 'PHP', logo: { src: PhpLogo, width: 64, height: 34, alt: 'PHP logo' }, + category: 'Web', }, { href: 'aspnet-core-v6', header: 'ASP.NET Core 6.0', logo: { src: DotnetLogo, alt: 'Dotnet logo' }, + category: 'Web', }, { href: 'aspnet-core-v3', header: 'ASP.NET Core 3.1', logo: { src: DotnetLogo, alt: 'Dotnet logo' }, + category: 'Web', }, ]; -export function VerifyIntegrationCards(): ReactElement { +function IntegrationCardsList({ category }: { category?: string }): ReactElement { + const displayGuides = category ? guides.filter(g => g.category === category) : guides; return (
- {guides.map(guide => ( + {displayGuides.map(guide => ( ); } + +export const VerifyIntegrationCards = () => ; +export const VerifyIntegrationCardsWeb = () => ; +export const VerifyIntegrationCardsSpa = () => ; +export const VerifyIntegrationCardsCiam = () => ; diff --git a/src/Homepage/logos/eids/freja.svg b/src/images/logos/eids/freja.svg similarity index 100% rename from src/Homepage/logos/eids/freja.svg rename to src/images/logos/eids/freja.svg diff --git a/src/Homepage/logos/eids/ftn.svg b/src/images/logos/eids/ftn.svg similarity index 100% rename from src/Homepage/logos/eids/ftn.svg rename to src/images/logos/eids/ftn.svg diff --git a/src/Homepage/logos/eids/idin.svg b/src/images/logos/eids/idin.svg similarity index 100% rename from src/Homepage/logos/eids/idin.svg rename to src/images/logos/eids/idin.svg diff --git a/src/Homepage/logos/eids/mitid-erhverv.svg b/src/images/logos/eids/mitid-erhverv.svg similarity index 100% rename from src/Homepage/logos/eids/mitid-erhverv.svg rename to src/images/logos/eids/mitid-erhverv.svg diff --git a/src/Homepage/logos/eids/mitid.svg b/src/images/logos/eids/mitid.svg similarity index 100% rename from src/Homepage/logos/eids/mitid.svg rename to src/images/logos/eids/mitid.svg diff --git a/src/Homepage/logos/eids/no-bankid.svg b/src/images/logos/eids/no-bankid.svg similarity index 100% rename from src/Homepage/logos/eids/no-bankid.svg rename to src/images/logos/eids/no-bankid.svg diff --git a/src/Homepage/logos/eids/personalausweis.svg b/src/images/logos/eids/personalausweis.svg similarity index 100% rename from src/Homepage/logos/eids/personalausweis.svg rename to src/images/logos/eids/personalausweis.svg diff --git a/src/Homepage/logos/eids/se-bankid.svg b/src/images/logos/eids/se-bankid.svg similarity index 100% rename from src/Homepage/logos/eids/se-bankid.svg rename to src/images/logos/eids/se-bankid.svg diff --git a/src/Homepage/logos/eids/vipps.svg b/src/images/logos/eids/vipps.svg similarity index 100% rename from src/Homepage/logos/eids/vipps.svg rename to src/images/logos/eids/vipps.svg diff --git a/src/Homepage/logos/integrations/auth0.svg b/src/images/logos/integrations/auth0.svg similarity index 100% rename from src/Homepage/logos/integrations/auth0.svg rename to src/images/logos/integrations/auth0.svg diff --git a/src/Homepage/logos/integrations/aws-cognito.svg b/src/images/logos/integrations/aws-cognito.svg similarity index 100% rename from src/Homepage/logos/integrations/aws-cognito.svg rename to src/images/logos/integrations/aws-cognito.svg diff --git a/src/Homepage/logos/integrations/csharp.svg b/src/images/logos/integrations/csharp.svg similarity index 100% rename from src/Homepage/logos/integrations/csharp.svg rename to src/images/logos/integrations/csharp.svg diff --git a/src/Homepage/logos/integrations/dotnet.svg b/src/images/logos/integrations/dotnet.svg similarity index 100% rename from src/Homepage/logos/integrations/dotnet.svg rename to src/images/logos/integrations/dotnet.svg diff --git a/src/Homepage/logos/integrations/expo.svg b/src/images/logos/integrations/expo.svg similarity index 100% rename from src/Homepage/logos/integrations/expo.svg rename to src/images/logos/integrations/expo.svg diff --git a/src/Homepage/logos/integrations/firebase.svg b/src/images/logos/integrations/firebase.svg similarity index 100% rename from src/Homepage/logos/integrations/firebase.svg rename to src/images/logos/integrations/firebase.svg diff --git a/src/Homepage/logos/integrations/javascript.svg b/src/images/logos/integrations/javascript.svg similarity index 100% rename from src/Homepage/logos/integrations/javascript.svg rename to src/images/logos/integrations/javascript.svg diff --git a/src/Homepage/logos/integrations/kotlin.svg b/src/images/logos/integrations/kotlin.svg similarity index 100% rename from src/Homepage/logos/integrations/kotlin.svg rename to src/images/logos/integrations/kotlin.svg diff --git a/src/Homepage/logos/integrations/nodejs.svg b/src/images/logos/integrations/nodejs.svg similarity index 100% rename from src/Homepage/logos/integrations/nodejs.svg rename to src/images/logos/integrations/nodejs.svg diff --git a/src/Homepage/logos/integrations/okta.svg b/src/images/logos/integrations/okta.svg similarity index 100% rename from src/Homepage/logos/integrations/okta.svg rename to src/images/logos/integrations/okta.svg diff --git a/src/Homepage/logos/integrations/onelogin.svg b/src/images/logos/integrations/onelogin.svg similarity index 100% rename from src/Homepage/logos/integrations/onelogin.svg rename to src/images/logos/integrations/onelogin.svg diff --git a/src/Homepage/logos/integrations/php.png b/src/images/logos/integrations/php.png similarity index 100% rename from src/Homepage/logos/integrations/php.png rename to src/images/logos/integrations/php.png diff --git a/src/Homepage/logos/integrations/php.svg b/src/images/logos/integrations/php.svg similarity index 100% rename from src/Homepage/logos/integrations/php.svg rename to src/images/logos/integrations/php.svg diff --git a/src/Homepage/logos/integrations/ping-identity.svg b/src/images/logos/integrations/ping-identity.svg similarity index 100% rename from src/Homepage/logos/integrations/ping-identity.svg rename to src/images/logos/integrations/ping-identity.svg diff --git a/src/Homepage/logos/integrations/python.svg b/src/images/logos/integrations/python.svg similarity index 100% rename from src/Homepage/logos/integrations/python.svg rename to src/images/logos/integrations/python.svg diff --git a/src/Homepage/logos/integrations/react.svg b/src/images/logos/integrations/react.svg similarity index 100% rename from src/Homepage/logos/integrations/react.svg rename to src/images/logos/integrations/react.svg diff --git a/src/Homepage/logos/integrations/swift.svg b/src/images/logos/integrations/swift.svg similarity index 100% rename from src/Homepage/logos/integrations/swift.svg rename to src/images/logos/integrations/swift.svg diff --git a/src/Homepage/logos/integrations/vuejs.svg b/src/images/logos/integrations/vuejs.svg similarity index 100% rename from src/Homepage/logos/integrations/vuejs.svg rename to src/images/logos/integrations/vuejs.svg diff --git a/src/Homepage/logos/integrations/wordpress.svg b/src/images/logos/integrations/wordpress.svg similarity index 100% rename from src/Homepage/logos/integrations/wordpress.svg rename to src/images/logos/integrations/wordpress.svg diff --git a/src/pages/index.mdx b/src/pages/index.mdx index 9921284e..72b19f04 100644 --- a/src/pages/index.mdx +++ b/src/pages/index.mdx @@ -4,7 +4,7 @@ subtitle: Welcome to the API documentation for Idura Verify & Idura Document Sig --- import { ProductCards } from '../Homepage/ProductCards'; -import { VerifyIntegrationCards } from '../Homepage/VerifyIntegrationCards'; +import { VerifyIntegrationCards } from '../components/VerifyIntegrationCards'; import { SignaturesIntegrationCards } from '../Homepage/SignaturesIntegrationCards'; import { EidCards } from '../Homepage/eIDCards'; import { DeveloperToolsCards } from '../Homepage/DeveloperToolsCards'; From 4e7dcae57d48e7c70437b1bab9ac9dc4403b041c Mon Sep 17 00:00:00 2001 From: nmoskaleva Date: Wed, 1 Apr 2026 11:04:37 +0200 Subject: [PATCH 2/4] Update Verify's "Getting Started" section to improve developer experience. This commit restructures the documentation to separate conceptual learning from actionable tasks and help developers find their way to the product faster. - Moved OIDC theory into a new "How it works" section. - Made "Getting Started" a quickstart guide with actionable steps (Set up the Dashbaord -> Create test user -> Integrate -> Move to Production) - Removed the `/verify` index page and added a redirect to `/verify/getting-started/ instead. --- gatsby-node.ts | 123 +++++++++++++++++- src/components/AuthorizeURLBuilder.tsx | 5 +- src/components/Navigation.tsx | 1 + src/pages/index.mdx | 2 +- .../getting-started/dashboard-setup.mdx | 65 +++++++++ src/pages/verify/getting-started/index.mdx | 105 ++++++++------- .../verify/getting-started/production.mdx | 53 ++++++++ .../verify/getting-started/test-users.mdx | 24 ++++ .../verify/guides/caller-authentication.mdx | 2 +- src/pages/verify/guides/oidc-visualizer.mdx | 2 +- src/pages/verify/guides/production.mdx | 40 ------ .../guides/pushed-authorization-requests.mdx | 27 ++-- src/pages/verify/guides/test-users.mdx | 13 -- .../best-security-practices.mdx | 24 ++-- .../core-concepts.mdx} | 27 ++-- .../oidc-intro.mdx | 32 ++--- .../overview.mdx | 6 +- src/pages/verify/index.mdx | 29 ++--- src/pages/verify/integrations/firebase.mdx | 2 +- src/pages/verify/reference/glossary.mdx | 8 +- src/snippets/generate-client-secret.mdx | 24 ++++ src/snippets/images/oauth2-client-secret.png | Bin 49533 -> 74961 bytes 22 files changed, 421 insertions(+), 193 deletions(-) create mode 100644 src/pages/verify/getting-started/dashboard-setup.mdx create mode 100644 src/pages/verify/getting-started/production.mdx create mode 100644 src/pages/verify/getting-started/test-users.mdx delete mode 100644 src/pages/verify/guides/production.mdx delete mode 100644 src/pages/verify/guides/test-users.mdx rename src/pages/verify/{getting-started => how-it-works}/best-security-practices.mdx (81%) rename src/pages/verify/{getting-started/basics.mdx => how-it-works/core-concepts.mdx} (74%) rename src/pages/verify/{getting-started => how-it-works}/oidc-intro.mdx (94%) rename src/pages/verify/{getting-started => how-it-works}/overview.mdx (94%) create mode 100644 src/snippets/generate-client-secret.mdx diff --git a/gatsby-node.ts b/gatsby-node.ts index dee554d2..e69d8a03 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -197,7 +197,6 @@ export const createPages: GatsbyNode['createPages'] = ({ actions }) => { isPermanent: true, force: true, }); - createRedirect({ fromPath: '/how-to/*', toPath: '/verify/how-to/:splat', @@ -210,6 +209,128 @@ export const createPages: GatsbyNode['createPages'] = ({ actions }) => { isPermanent: true, force: true, }); + createRedirect({ + fromPath: '/verify/articles/custom-ui-samples', + toPath: '/verify/reference/samples', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/articles/custom-ui-css', + toPath: '/verify/guides/custom-styling/#custom-css-adding-a-stylesheet', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify', + toPath: '/verify/getting-started/', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/articles/custom-ui-css', + toPath: '/verify/guides/custom-styling/#custom-css-adding-a-stylesheet', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/guides/test-users/', + toPath: '/verify/getting-started/test-users/', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/overview', + toPath: '/verify/how-it-works/overview', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics', + toPath: '/verify/how-it-works/core-concepts', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics/#tenants', + toPath: '/verify/how-it-works/core-concepts/#tenants', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics/#domains', + toPath: '/verify/how-it-works/core-concepts/#domains', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics/#bring-your-own-domain', + toPath: '/verify/how-it-works/core-concepts/#bring-your-own-domain', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics/#applications', + toPath: '/verify/how-it-works/core-concepts/#applications', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics/#eid-providers', + toPath: '/verify/how-it-works/core-concepts/#eid-providers', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/oidc-intro/', + toPath: '/verify/how-it-works/oidc-intro/', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/', + toPath: '/verify/how-it-works/best-security-practices/', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/#authorization-code-flow', + toPath: '/verify/how-it-works/best-security-practices/#authorization-code-flow', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: + '/verify/getting-started/best-security-practices/#pushed-authorization-requests/#the-nonce-parameter', + toPath: + '/verify/how-it-works/best-security-practices/#pushed-authorization-requests/#the-nonce-parameter', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/#the-state-parameter', + toPath: '/verify/how-it-works/best-security-practices/#the-state-parameter', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/#always-validating-jwts', + toPath: '/verify/how-it-works/best-security-practices/#always-validating-jwts', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/#client-authentication', + toPath: '/verify/how-it-works/best-security-practices/#client-authentication', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/#avoid-implicit-flow', + toPath: '/verify/how-it-works/best-security-practices/#avoid-implicit-flow', + isPermanent: true, + force: true, + }); }; // https://www.gatsbyjs.com/docs/conceptual/data-fetching/#source-data-to-be-queried-at-build-time diff --git a/src/components/AuthorizeURLBuilder.tsx b/src/components/AuthorizeURLBuilder.tsx index acc9b82a..f051225f 100644 --- a/src/components/AuthorizeURLBuilder.tsx +++ b/src/components/AuthorizeURLBuilder.tsx @@ -485,10 +485,7 @@ export default function AuthorizeURLBuilder(props: { helpText={ Also known as{' '} - + callback URL . diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx index 24a5275e..df9e06bc 100644 --- a/src/components/Navigation.tsx +++ b/src/components/Navigation.tsx @@ -18,6 +18,7 @@ const VERIFY_CATEGORIES = [ 'eIDs', 'Guides & Tools', 'Integrations', + 'How it works', 'Reference', ]; diff --git a/src/pages/index.mdx b/src/pages/index.mdx index 72b19f04..4a84700a 100644 --- a/src/pages/index.mdx +++ b/src/pages/index.mdx @@ -15,7 +15,7 @@ import { DeveloperToolsCards } from '../Homepage/DeveloperToolsCards'; ## Integrate Idura Verify -Idura Verify can be integrated with any tech stack using the standard [OpenID Connect (OIDC) protocol](/verify/getting-started/oidc-intro/). +Idura Verify can be integrated with any tech stack using the standard [OpenID Connect (OIDC) protocol](/verify/how-it-works/oidc-intro/). You don't need to be an identity expert to integrate Idura: a trusted OIDC client library or one of our dedicated SDKs will handle most of the complexity for you. Idura can also easily connect to your existing CIAM system, such as Auth0, AWS Cognito, or Firebase. diff --git a/src/pages/verify/getting-started/dashboard-setup.mdx b/src/pages/verify/getting-started/dashboard-setup.mdx new file mode 100644 index 00000000..299a48a6 --- /dev/null +++ b/src/pages/verify/getting-started/dashboard-setup.mdx @@ -0,0 +1,65 @@ +--- +product: verify +category: Getting Started +sort: 1 +title: Set up the Dashboard +subtitle: Create a tenant, register an application, and generate client credentials. +--- + +Before you can integrate Idura Verify into your application, you need to configure your environment in the Idura Dashboard. +This takes about two minutes and will give you the client credentials required to build your own eID-based login flows. + +## Create a tenant + +A [tenant](/verify/how-it-works/core-concepts/#tenants) represents your organization's isolated environment at Idura. + +1. [Sign up for a free test account](https://dashboard.idura.app/signup) to access the Idura Dashboard. +2. You will be prompted to create your first tenant. + + + **Risk-free testing**: Your free account includes a sandbox environment with unlimited test + logins, allowing you to build and test your integration without any obligations or unexpected + costs. + + +## Register a domain + +Everything you do with Idura requires a [domain](/verify/how-it-works/core-concepts/#domains) to route your authentication requests. + +1. Go to the [**Domains** tab](https://dashboard.idura.app/domains) in your dashboard. +2. Click **Register domain**. +3. Select your domain type. We recommend starting with a standard `.test.idura.broker` domain for your local development and testing. +4. Type your domain name in the **Domain settings** field. If your company name is Acme Corp, your first domain may look somethig like `acme-corp.test.idura.broker`. + +## Register an application + +An [application](/verify/how-it-works/core-concepts/#applications) represents the software you are building (e.g., your React frontend or Node.js backend). +Registering an application generates the client credentials you will use in your code to configure your software to communicate with Idura Verify. + +1. Add a [new login application](https://dashboard.idura.app/applications/add/) from the **Applications** tab of your dashboard. +2. Configure your new application: + +- **Name:** Choose a recognizable name. +- **Domain:** Select the domain you registered in the previous step. +- **Client ID / Realm:** You can use the auto-generated identifier (e.g., `urn:my:application:identifier:123`) or create a custom one. +- **Redirect URL(s):** Enter the [callback URL](/verify/reference/glossary/#redirect-uri) where Idura should send users after they log in (e.g., `http://localhost:3000/api/auth/callback` for local development). + _Note: Wildcards are not supported, but you can always add more URLs to the list._ +- **Application Type:** Select the option that matches your tech stack (e.g., Single Page Application -> React, Regular Web Application -> Node.js). This will point you to the right integration guide once the application is created. + +3. Click **Create Application** to save the initial configurations. + Your application settings will now display the **Client ID / Realm**. You will need to paste it in your code once ready to integrate. + +### Generate a client secret + +import GenerateClientSecretSnippet from '../../../snippets/generate-client-secret.mdx'; + + + +## What's next? + +Your dashboard is configured and your API credentials are ready to use. + +To be able to run test logins, you need to create a test user for the eID(s) you're planning to use. +Note that you can't use your real, personal eID in a test environment. + +Proceed to [Creating Test Users →](/verify/getting-started/test-users/) diff --git a/src/pages/verify/getting-started/index.mdx b/src/pages/verify/getting-started/index.mdx index 677a72fb..72f14d3f 100644 --- a/src/pages/verify/getting-started/index.mdx +++ b/src/pages/verify/getting-started/index.mdx @@ -2,55 +2,60 @@ product: verify category: Getting Started sort: 0 -title: Get started with Idura Verify +title: Getting Started +subtitle: A quickstart guide to get up and running with Idura Verify. Follow the steps below to authenticate your first user. --- -import { isIndexPage } from '../../../utils'; - -import { graphql as gatsbyGraphql, Link } from 'gatsby'; -export const pageQuery = gatsbyGraphql` - query GettingStarted { - pages: allMdx( - filter: { - frontmatter: { - product: { eq: "verify" } - category: { eq: "Getting Started" } - } - } - sort: {frontmatter: {sort: ASC}} - ) { - edges { - node { - __typename - id - frontmatter { - title - category - subtitle - } - fields { - slug - } - internal { - contentFilePath - } - } - } - } - } -`; - -Below you will find a list of topics to get you started with Idura Verify: - -
    - {props.data.pages.edges - .map(edge => edge.node) - .filter(node => !isIndexPage(node)) - .map(node => ( -
  • - {node.frontmatter.title} -
    - {node.frontmatter.subtitle} -
  • - ))} -
+import { + VerifyIntegrationCardsWeb, + VerifyIntegrationCardsSpa, + VerifyIntegrationCardsCiam, +} from '../../../components/VerifyIntegrationCards'; + +## Step 1: Set up the Dashboard + +Before writing any code, you need to create a tenant and register your own Idura domain and application to get your API credentials. + +[Set up the Dashboard →](/verify/getting-started/dashboard-setup/) +Learn how to navigate the Idura Dashboard, register a tenant, and create your first domain and application. + +## Step 2: Create a test user + +You cannot use your real, personal eID to test integrations in a development environment. Instead, national eID schemes require dummy accounts for testing. + +[Create test users →](/verify/getting-started/test-users/) +Learn how to generate test identities for the eIDs you'll be working with. + +## Step 3: Choose your integration + +Ready to build? We provide SDKs and step-by-step guides to integrate Idura Verify into your existing tech stack. Select your framework below. + +### SPA & Native + + + +### Backend & Web + + + +### Identity platforms + + + +### Not ready to write code yet? + +You can simulate a full authentication flow right from your browser using our developer tools: + +- [Authorize URL Builder →](/verify/guides/authorize-url-builder/) Construct and test specific login requests, tuning the parameters to your needs. +- [OIDC Visualizer →](/verify/guides/oidc-visualizer/) Step through a complete login flow. Inspect requests and responses exchanged during the process, decode JWT tokens, and review user claims returned by the eID. + +Or build your knowledge first by exploring our resources: + +- [Understand OpenID Connect →](/verify/how-it-works/oidc-intro/) Learn about the different OpenID Connect flows supported by Idura Verify, authorization request parameters, JWT tokens, and more. +- [Review Security Best Practices →](/verify/how-it-works/best-security-practices/) See guidelines for securing your implementation and choosing the right OIDC flow for your application architecture. + +## Step 4: Move to Production + +Once your integration is working locally with test users, it's time to upgrade. + +- [Get Ready for Production →](/verify/getting-started/production/) Review our checklist for applying for eIDs you need and going live. diff --git a/src/pages/verify/getting-started/production.mdx b/src/pages/verify/getting-started/production.mdx new file mode 100644 index 00000000..6e117e84 --- /dev/null +++ b/src/pages/verify/getting-started/production.mdx @@ -0,0 +1,53 @@ +--- +product: verify +category: Getting Started +sort: 3 +title: Get ready for production +subtitle: Upgrade your account, apply for eIDs, and go live. +--- + +Once your integration is working locally with test users, you are ready to move to production. + + + **A paid subscription is required.** To accept real eID logins and set up a production domain, you + must upgrade your free test account to a paid plan. + + +## Moving to production + +1. **Upgrade your subscription.** + Go to the [**Billing** tab](https://dashboard.idura.app/billing) in the Idura Dashboard and choose a plan that suits your expected usage. + +2. **Apply for production eIDs.** + Using real national eIDs requires formal approval and production certificates from the respective national authorities. + + + + + +**Ordering eIDs for production** + +Each eID provider has specific requirements. Use the links below to review the necessary steps for each provider. +_Tip: Start the application process as early as possible. Approval and certificate issuance can take several business days depending on the eID provider._ + +- [FrejaID](/verify/e-ids/frejaid/#ordering-frejaid) +- [Swedish BankID](/verify/e-ids/swedish-bankid/#ordering-swedish-bankid) +- [Norwegian BankID](/verify/e-ids/norwegian-bankid/#ordering-norwegian-bankid) +- [German Personalausweis](/verify/e-ids/german-personalausweis/#getting-ready-for-production) +- [Vipps MobilePay](/verify/e-ids/vipps-mobilepay/#ordering-vipps-mobilepay) +- [Danish MitID](/verify/e-ids/danish-mitid/#order-mitid-for-production) +- [Finnish Trust Network](/verify/e-ids/finnish-trust-network/#ordering-a-production-agreement) +- [Dutch iDIN](/verify/e-ids/dutch-idin/#ordering-idin) + + + +3. **Set up your production environment.** + - Change the environment from **Test** to **Production** in the top left corner of your Idura Dashboard. + - Go to the **Domains** tab and create a production domain. + _Note that if you choose a domain that ends with something other than `idura.broker`, we recommend going with the Idura-managed option (**Managed SSL certificate**) for SSL certificate._ + - Go to the **Applications** tab and register your production application. + _The **Client ID** of your production application must be unique._ + +4. **Update your codebase.** + Configure your website or application with the new production domain and API credentials. + You are now ready to accept real eID logins in your production application! Run a quick test with a real eID to verify everything is working as expected. diff --git a/src/pages/verify/getting-started/test-users.mdx b/src/pages/verify/getting-started/test-users.mdx new file mode 100644 index 00000000..b42c0f92 --- /dev/null +++ b/src/pages/verify/getting-started/test-users.mdx @@ -0,0 +1,24 @@ +--- +product: verify +category: Getting Started +sort: 2 +title: Create test users +subtitle: Generate sandbox identities to test your eID integrations in development. +--- + +import TestUsersSetupLinks from '../../../snippets/test-users-setup-instructions'; + +To run test logins with most eIDs, you'll need to create a test user and install a test app. +Find instructions for each eID in the links below. + + + +## What's next? + +Once your [dashboard is configured](/verify/getting-started/dashboard-setup/) and test users are ready, choose your path forward: + +- **[Choose your integration →](/verify/integrations/)** Ready to start building? Find SDKs and follow the step-by-step guides for your tech stack. +- **[Understand OpenID Connect →](/verify/how-it-works/oidc-intro/)** + Not ready to write code yet? Learn about supported OIDC flows and security best practices. +- **[Get ready for production →](/verify/getting-started/production/)** + Already built and tested your integration locally? Review our checklist for upgrading your account and applying for real eIDs. diff --git a/src/pages/verify/guides/caller-authentication.mdx b/src/pages/verify/guides/caller-authentication.mdx index 52e77886..6792cb7a 100644 --- a/src/pages/verify/guides/caller-authentication.mdx +++ b/src/pages/verify/guides/caller-authentication.mdx @@ -15,7 +15,7 @@ This creates a secure, phishing-resistant way to confirm who you are talking to ## The CIBA flow -Caller Authentication is built on the [**Client-Initiated Backchannel Authentication (CIBA) flow**](/verify/getting-started/oidc-intro/#authenticate-with-ciba). +Caller Authentication is built on the [**Client-Initiated Backchannel Authentication (CIBA) flow**](/verify/how-it-works/oidc-intro/#authenticate-with-ciba). With CIBA, the client application provides a hint (e.g. the user's SSN) that triggers an authentication request to the user's device. The user can then approve the request and complete the authentication process on their device. diff --git a/src/pages/verify/guides/oidc-visualizer.mdx b/src/pages/verify/guides/oidc-visualizer.mdx index 20f48593..4cd8030d 100644 --- a/src/pages/verify/guides/oidc-visualizer.mdx +++ b/src/pages/verify/guides/oidc-visualizer.mdx @@ -22,7 +22,7 @@ and **Idura Verify acting as the Authorization Server**, so you can understand w ## Authorization Code Flow -[Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) is the most common OIDC flow for web applications. +[Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) is the most common OIDC flow for web applications. The diagram below shows how the Client Application and Authorization Server interact to complete this flow. ![Authorization Code Flow ](./images/authorization_code_flow_diagram.png) diff --git a/src/pages/verify/guides/production.mdx b/src/pages/verify/guides/production.mdx deleted file mode 100644 index 43cc3682..00000000 --- a/src/pages/verify/guides/production.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -product: verify -category: Guides & Tools -sort: 1 -title: Get ready for production ---- - -Once you have developed and tested your application to work with test user accounts, you are ready to move ahead and work with real user eID accounts. - -_Please note_ that for production usage, you need a paid subscription. - -Follow these steps to get ready for production: - -1. If you haven't done so already, go to [dashboard.idura.app](https://dashboard.idura.app/billing), select the **Billing** tab, and choose a plan that suits your expected usage. -2. Next, you must acquire a production certificate for the eID provider(s) you plan to use in production. - - - - - -**Ordering eIDs for production** - -Each eID provider has specific requirements. Use the links below to review the necessary steps for each provider. - -- [Swedish BankID](/verify/e-ids/swedish-bankid/#ordering-swedish-bankid) -- [Norwegian BankID](/verify/e-ids/norwegian-bankid/#ordering-norwegian-bankid) -- [Vipps MobilePay](/verify/e-ids/vipps-mobilepay/#ordering-vipps-mobilepay) -- [Danish MitID](/verify/e-ids/danish-mitid/#order-mitid-for-production) -- [Finnish Trust Network](/verify/e-ids/finnish-trust-network/#ordering-a-production-agreement) - - - -3. Change the environment from **Test** to **Production** on the top left corner of the Dashboard. -4. Go to the **Domains** tab and set up a production domain. - - Note that if you choose a domain that ends with something other than `idura.broker`, we recommend going with the Idura-managed option ("Managed SSL certificate") for SSL certificate. -5. Go to the **Applications** tab and register your production application: - - The **Client ID** must be unique; it cannot be the same as any of your other applications -6. Configure your website or application with the new domain, Client ID, and Client secret. - -Once you have been through these steps, you are ready to start using real Swedish BankID, Danish MitID, and others in your production application. diff --git a/src/pages/verify/guides/pushed-authorization-requests.mdx b/src/pages/verify/guides/pushed-authorization-requests.mdx index 2858204d..96a2015a 100644 --- a/src/pages/verify/guides/pushed-authorization-requests.mdx +++ b/src/pages/verify/guides/pushed-authorization-requests.mdx @@ -5,9 +5,12 @@ sort: 1 title: Pushed Authorization Requests (PAR) --- -Pushed Authorization Requests (PAR) -is an OAuth 2.0 extension that allows sending [authorization request parameters](/verify/getting-started/oidc-intro/#authorize-request-parameters) -to the authorization server via a POST request, rather than in the browser's URL query string. + + Pushed Authorization Requests (PAR) + +is an OAuth 2.0 extension that allows sending [authorization request +parameters](/verify/how-it-works/oidc-intro/#authorize-request-parameters) to the authorization +server via a POST request, rather than in the browser's URL query string. PAR enhances security by mitigating risks associated with exposing sensitive data in URLs. It also allows the authorization server to authenticate the client and validate the request early in the process (before any user interaction occurs), @@ -16,12 +19,12 @@ which can prevent attempts to spoof clients or otherwise tamper with or misuse a Using PAR improves [Telemetry & Observability](/verify/guides/telemetry/#par) for your Idura applications: it helps you trace authorization requests by giving you a `Trace-Id` to follow immediately and directly to your backend. -PAR can be used with any [OpenID Connect flow](/verify/getting-started/oidc-intro/#supported-openid-connect-flows) that involves authorization requests sent via the browser, -including the [Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) and the [Authorization Code Flow with PKCE](/verify/getting-started/oidc-intro/#authenticate-with-pkce). +PAR can be used with any [OpenID Connect flow](/verify/how-it-works/oidc-intro/#supported-openid-connect-flows) that involves authorization requests sent via the browser, +including the [Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) and the [Authorization Code Flow with PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce). ## How PAR works -[Regular authorization requests](/verify/getting-started/glossary/#authorization-request-authorize-url) are made by redirecting the user's browser to the OAuth2 authorization endpoint (`/oauth2/authorize`) with all parameters included in the URL. +[Regular authorization requests](/verify/reference/glossary/#authorization-request-authorize-url) are made by redirecting the user's browser to the OAuth2 authorization endpoint (`/oauth2/authorize`) with all parameters included in the URL. The process with PAR is slightly different: @@ -37,23 +40,23 @@ You can start using PAR in place of standard authorization requests by following ### 1: Push the authorization request from your backend Send a POST request from your backend to the PAR endpoint. The PAR endpoint URL can be found in your -[OIDC Discovery Document](/verify/getting-started/glossary/#oidc-discovery-document-well-knownopenid-configuration) under `pushed_authorization_request_endpoint`. +[OIDC Discovery Document](/verify/reference/glossary/#oidc-discovery-document-well-knownopenid-configuration) under `pushed_authorization_request_endpoint`. Your POST request should include: - The same parameters you would normally send in an authorization request (e.g. `response_type`, `scope`, `redirect_uri`, `state`). - For the complete list of authorization request parameters, see [Authorize Request Parameters](/verify/getting-started/oidc-intro/#authorize-request-parameters). -- Client authentication credentials (for [confidential clients](/verify/getting-started/glossary/#confidential-client)): + For the complete list of authorization request parameters, see [Authorize Request Parameters](/verify/how-it-works/oidc-intro/#authorize-request-parameters). +- Client authentication credentials (for [confidential clients](/verify/reference/glossary/#confidential-client)): - either `client_id` and `client_secret` (included in the Basic Authorization header) or - `client_assertion` and `client_assertion_type` (included in the request body), when using [Private Key JWT](/verify/guides/privatekey-jwt/). -- `code_challenge` and `code_challenge_method` (for [public clients](/verify/getting-started/glossary/#public-clients) or clients implementing [Authorization Code Flow with PKCE](/verify/getting-started/oidc-intro/#authenticate-with-pkce)). +- `code_challenge` and `code_challenge_method` (for [public clients](/verify/reference/glossary/#public-clients) or clients implementing [Authorization Code Flow with PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)). -The [PKCE](/verify/getting-started/glossary/#pkce-proof-key-for-code-exchange) extension to the Authorization Code Flow is required for public clients and recommended for confidential clients. +The [PKCE](/verify/reference/glossary/#pkce-proof-key-for-code-exchange) extension to the Authorization Code Flow is required for public clients and recommended for confidential clients. It offers stronger protection against the misuse or injection of authorization codes, making your implementation more secure. -For more details, see [OpenID Connect best security practices](/verify/getting-started/best-security-practices/verify/getting-started/best-security-practices/#authorization-code-flow). +For more details, see [OpenID Connect best security practices](/verify/how-it-works/best-security-practices/#authorization-code-flow). diff --git a/src/pages/verify/guides/test-users.mdx b/src/pages/verify/guides/test-users.mdx deleted file mode 100644 index b0739b96..00000000 --- a/src/pages/verify/guides/test-users.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -product: verify -category: Guides & Tools -sort: 0 -title: Creating test users -subtitle: How to create test users and set up test apps for different eIDs ---- -import TestUsersSetupLinks from '../../../snippets/test-users-setup-instructions'; - -To run test logins with most eIDs, you'll need to create a test user and install a test app. -Find instructions for each eID in the links below. - - diff --git a/src/pages/verify/getting-started/best-security-practices.mdx b/src/pages/verify/how-it-works/best-security-practices.mdx similarity index 81% rename from src/pages/verify/getting-started/best-security-practices.mdx rename to src/pages/verify/how-it-works/best-security-practices.mdx index cb5ee1fe..704be5e4 100644 --- a/src/pages/verify/getting-started/best-security-practices.mdx +++ b/src/pages/verify/how-it-works/best-security-practices.mdx @@ -1,6 +1,6 @@ --- product: verify -category: Getting Started +category: How it works sort: 3 title: OpenID Connect best security practices subtitle: Learn about key security guidelines for implementing basic OpenID Connect authentication in client applications. @@ -15,9 +15,9 @@ Idura Verify is an OpenID Provider, handling most of the process. However, it is ## Authorization Code Flow -The most secure method of performing OIDC authentication is the [Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow), or its extended version — [Authorization Code Flow with PKCE](/verify/getting-started/oidc-intro/#authenticate-with-pkce). +The most secure method of performing OIDC authentication is the [Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow), or its extended version — [Authorization Code Flow with PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce). -In the Authorization Code Flow, the client application exchanges an authorization code for tokens at the token endpoint. When using Idura Verify for eID authentication: After the end user successfully logs in with their [eID](/verify/e-ids) and is redirected back to the client application through the redirect URL, the client application retrieves the authorization code from the URL. The client application then uses this code to request an ID token from Idura Verify (see [code for token exchange](/verify/getting-started/oidc-intro/#exchange-the-code-for-a-token)). +In the Authorization Code Flow, the client application exchanges an authorization code for tokens at the token endpoint. When using Idura Verify for eID authentication: After the end user successfully logs in with their [eID](/verify/e-ids) and is redirected back to the client application through the redirect URL, the client application retrieves the authorization code from the URL. The client application then uses this code to request an ID token from Idura Verify (see [code for token exchange](/verify/how-it-works/oidc-intro/#exchange-the-code-for-a-token)). The Authorization Code Flow enhances security by mitigating replay attempts by attackers (when an attacker tries to reuse a valid intercepted token) and generally reduces the attack surface since ID tokens are not exposed in URLs. @@ -27,15 +27,15 @@ The Authorization Code Flow enhances security by mitigating replay attempts by a - Confidential clients — such as traditional server-based web applications – are encouraged to use the **PKCE flow** as well. This is a recommended approach, since **PKCE** provides strong protection against misuse and injection of authorization codes, making it a more secure option. - Alternatively, confidential clients can implement the **Authorization Code Flow**. - Confidential clients implementing the **Authorization Code Flow** (without **PKCE**) should take additional precautions, such as using the `nonce` parameter and the respective claim in the `id_token`, and one-time tokens carried in the `state` parameter. -- For use cases where authentication is initiated on one device but completed on another (e.g., a call center agent starts the authentication process for the end user), the back-channel [CIBA flow](/verify/getting-started/oidc-intro/#authenticate-with-ciba) is the right choice. -- The Implicit Flow is obsolete and [should not be used in production applications](/verify/getting-started/best-security-practices/#avoid-implicit-flow). +- For use cases where authentication is initiated on one device but completed on another (e.g., a call center agent starts the authentication process for the end user), the back-channel [CIBA flow](/verify/how-it-works/oidc-intro/#authenticate-with-ciba) is the right choice. +- The Implicit Flow is obsolete and [should not be used in production applications](/verify/how-it-works/best-security-practices/#avoid-implicit-flow). ## Pushed Authorization Requests In a standard authorization request, parameters are sent in a URI query string via a browser redirect. This approach has several limitations: - There’s no inherent cryptographic guarantee that the data hasn’t been tampered with or forged. For example, an attacker could try modifying the `scope` or `redirect_uri` parameters, potentially gaining unauthorized access or redirecting users to an unintended endpoint. -- Request parameters are exposed in URLs, which can leak to web server logs or other sites. This is particularly risky if [personally identifiable information (PII)](/verify/getting-started/glossary/#personally-identifiable-information-pii) is included. +- Request parameters are exposed in URLs, which can leak to web server logs or other sites. This is particularly risky if [personally identifiable information (PII)](/verify/reference/glossary/#personally-identifiable-information-pii) is included. - Authorization request URLs can become quite large, which may cause errors in request processing. [Pushed Authorization Requests (PAR)](/verify/guides/pushed-authorization-requests/) address these issues by allowing clients to send authorization request parameters in a **POST request directly from the backend** to the authorization server. @@ -51,11 +51,11 @@ Replacing regular authorization requests with PAR is a simple upgrade that helps `nonce` is used to associate an ID token to the specific authorization request and user session. -The client application should bind `nonce` to the user agent session and send it with the initial [authorization request](/verify/getting-started/oidc-intro/#example-authorization-url) to the OpenID Provider. The binding is done using HTTPOnly, Secure cookies, and preferably with a server-side encrypted value for the `nonce` (using authenticated encryption). -The OpenID Provider puts the received `nonce` value into the `id_token` that is issued as part of the [code exchange](/verify/getting-started/oidc-intro/#exchange-the-code-for-a-token) at the token endpoint. +The client application should bind `nonce` to the user agent session and send it with the initial [authorization request](/verify/how-it-works/oidc-intro/#example-authorization-url) to the OpenID Provider. The binding is done using HTTPOnly, Secure cookies, and preferably with a server-side encrypted value for the `nonce` (using authenticated encryption). +The OpenID Provider puts the received `nonce` value into the `id_token` that is issued as part of the [code exchange](/verify/how-it-works/oidc-intro/#exchange-the-code-for-a-token) at the token endpoint. -- `nonce` serves as a [token validation](/verify/getting-started/best-security-practices/#always-validating-jwts) parameter. If an attacker injects an authorization code in the authorization response, the `nonce` value in the client session and the `nonce` value in the `id_token` received from the token endpoint will not match, and the attack will be detected. -- `nonce` also helps protect against an attacker potentially intercepting a valid [`state` parameter](/verify/getting-started/best-security-practices/#the-state-parameter), but then providing a `code` value tied to a different session. This could be a concern for public clients, and, in theory, in some confidential client scenarios. +- `nonce` serves as a [token validation](/verify/how-it-works/best-security-practices/#always-validating-jwts) parameter. If an attacker injects an authorization code in the authorization response, the `nonce` value in the client session and the `nonce` value in the `id_token` received from the token endpoint will not match, and the attack will be detected. +- `nonce` also helps protect against an attacker potentially intercepting a valid [`state` parameter](/verify/how-it-works/best-security-practices/#the-state-parameter), but then providing a `code` value tied to a different session. This could be a concern for public clients, and, in theory, in some confidential client scenarios. **Best practice:** For confidential clients implementing the Authorization Code Flow, it is strongly recommended to always include a `nonce` parameter in authorization requests to protect against misuse of authorization codes. The client application should then validate the `nonce` in the received `id_token`, and not use any issued tokens until this check has succeeded. @@ -65,7 +65,7 @@ _For public clients using the PKCE flow, the `nonce` parameter can also provide The `state` parameter helps prevent Cross-Site Request Forgery (CSRF) attacks by maintaining state between the client application and the authorization server. -When initiating an [authorization request](<(/verify/getting-started/oidc-intro/#example-authorization-url)>), the client application generates a random value and includes it in the `state` parameter. +When initiating an [authorization request](/verify/how-it-works/oidc-intro/#example-authorization-url), the client application generates a random value and includes it in the `state` parameter. This random value links the request to the redirect URL to the client session. Once the user is authenticated, the authorization server redirects the user back to the client application's redirect URL, including the same `state` value in the URL. For example: `https://your-app.com/callback?code=authorization-code&state=unique-state-value` Similarly, if the `state` parameter was included in the authorization request, the error responses from the authorization server will also contain the `state` parameter, providing protection against attacker-forged error responses. @@ -77,7 +77,7 @@ Overall, the `state` parameter allows the client application to verify that the ## Always validating JWTs Upon successful user authentication, Idura Verify will issue an **[ID token](/verify/reference/token-contents/)** to the client application. `id_token` contains user authentication information in the form of a JSON Web Token (JWT). -However, receiving a JWT is not enough - your application must also [validate it](/verify/getting-started/oidc-intro/#validate-the-jwt). Without validation, there’s no guarantee that the token hasn’t been tampered with or forged. +However, receiving a JWT is not enough - your application must also [validate it](/verify/how-it-works/oidc-intro/#validate-the-jwt). Without validation, there’s no guarantee that the token hasn’t been tampered with or forged. _Note: `id_token` must be validated, even if using the `/userInfo` endpoint for personal data._ diff --git a/src/pages/verify/getting-started/basics.mdx b/src/pages/verify/how-it-works/core-concepts.mdx similarity index 74% rename from src/pages/verify/getting-started/basics.mdx rename to src/pages/verify/how-it-works/core-concepts.mdx index 44af79a6..25056028 100644 --- a/src/pages/verify/getting-started/basics.mdx +++ b/src/pages/verify/how-it-works/core-concepts.mdx @@ -1,32 +1,34 @@ --- product: verify -category: Getting Started +category: How it works sort: 1 -title: Learn the Basics +title: Core concepts subtitle: Learn the basics of Idura and familiarize yourself with the terminology. --- This document explains some of the basic terminology we use at Idura, and we try to relate these terms to concepts you are already familiar with. -This article introduces the following core concepts of Idura: **[Tenants](/verify/getting-started/basics/#tenants)**, **[Domains](/verify/getting-started/basics/#domains)**, **[Applications](/verify/getting-started/basics/#applications)**, and **[eID Providers](/verify/getting-started/basics/#eid-providers)**. +This article introduces the following core concepts of Idura: **[Tenants](/verify/how-it-works/core-concepts/#tenants)**, **[Domains](/verify/how-it-works/core-concepts/#domains)**, **[Applications](/verify/how-it-works/core-concepts/#applications)**, and **[eID Providers](/verify/how-it-works/core-concepts/#eid-providers)**. One important distinction in Idura Verify is the separation of **Test** and **Production**. Inside each tenant, you may toggle the setup between Test and Production to configure each environment separately. -To set up a production domain you must first upgrade your free subscription to a paid subscription.   +_Note: To set up a production domain, you must first upgrade your free subscription to a paid subscription._ -For illustration purposes, we will use a fictitious company named _Secure Insurance_ that wants to use Idura for authentication. They have both a web and a mobile application, and they want their users to be able to log in with Swedish BankID and Danish MitID. +For illustration purposes, we will use a fictitious company named Secure Insurance that wants to use Idura for authentication. They have both a web and a mobile application, and they want their users to be able to log in with Swedish BankID and Danish MitID. ## Tenants If you haven't already [signed up](https://dashboard.idura.app/signup?utm_source=docs) for an Idura account, feel free - it's free. -When you sign up for the first time, you will be asked to create your first tenant and your first _domain_ along with it. In Idura, a tenant is the **logical isolation unit** that isolates you and your data from other Idura tenants. The term describes a software architecture where a single instance of the software serves multiple tenants. No tenant can access the instance of another tenant, even though the software may be running on the same machine. +In Idura, a tenant is the **logical isolation unit** that isolates you and your data from other Idura tenants. +The term describes a software architecture where a single instance of the software serves multiple tenants. +No tenant can access the instance of another tenant, even though the software may be running on the same machine. -Tenant characteristics: +**Tenant characteristics:** - The tenant name has to be unique. It is used primarily for your reference and communication purposes and carries no formal significance. - The tenant name can be changed at any time after creation. @@ -36,15 +38,14 @@ You can create additional tenants at any time. To do so, go to the upper-right c ## Domains -As discussed in the previous section, when you create a new account with Idura, you also create your first domain. Typically, your first domain would be something like `secure-insurance-test.idura.broker`. - A domain in Idura Verify is the DNS domain on which you call our service to perform authentication. +Typically, your first domain would be something like `secure-insurance-test.idura.broker`. -Domains are registered for either test or production and as such determine whether you can use test eID accounts or real, live eID accounts. +Domains are registered for either test or production and determine whether you can use test user identities or real eID accounts. -As such, **the domain is the key distinction between test and production.** +As such, **the domain is the key distinction between Test and Production.** @@ -89,7 +90,3 @@ In most cases, this is handled through the intermediary of Idura, although in so More detail on the formalities and process can be found in the section about [eIDs](/verify/e-ids/). - -## Where to go from here - -This section introduced several core concepts of Idura. Next, we recommend learning [how Idura supports the OpenID Connect protocol](/verify/getting-started/oidc-intro/) and reviewing [best security practices for implementing OpenID Connect authentication](/verify/getting-started/best-security-practices/) in client applications. diff --git a/src/pages/verify/getting-started/oidc-intro.mdx b/src/pages/verify/how-it-works/oidc-intro.mdx similarity index 94% rename from src/pages/verify/getting-started/oidc-intro.mdx rename to src/pages/verify/how-it-works/oidc-intro.mdx index 6e6712e0..dbe9aea7 100644 --- a/src/pages/verify/getting-started/oidc-intro.mdx +++ b/src/pages/verify/how-it-works/oidc-intro.mdx @@ -1,6 +1,6 @@ --- product: verify -category: Getting Started +category: How it works sort: 2 title: Using OpenID Connect subtitle: Learn how Idura supports the OpenID Connect protocol. @@ -14,23 +14,23 @@ Idura Verify is an OpenID Provider. It is integrated through the authentication The OpenID Connect(OIDC) protocol defines different strategies (flows) to authenticate users. Idura Verify supports five different OpenID Connect flows: -#### [1. The Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) +#### [1. The Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) The Authorization Code Flow is used for traditional server-based web applications, also referred to as _confidential clients_. These applications can securely store a client secret and establish back-channel communication with the Idura Verify service. This facilitates a secure [code-for-token exchange](#exchange-the-code-for-a-token) during authentication. -#### [2. The PKCE Flow](/verify/getting-started/oidc-intro/#authenticate-with-pkce) +#### [2. The PKCE Flow](/verify/how-it-works/oidc-intro/#authenticate-with-pkce) The PKCE Flow (pronounced _pixy_) can be used by _public clients_ such as single-page applications (SPAs) and native applications that cannot keep a secret. With PKCE, a one-time secret is generated and used for the code exchange. -#### [3. The Implicit Flow](/verify/getting-started/oidc-intro/#authenticate-with-implicit-flow) +#### [3. The Implicit Flow](/verify/how-it-works/oidc-intro/#authenticate-with-implicit-flow) The Implicit Flow returns a token directly in the browser. Support for this flow is being discontinued, although it will continue to function on test domains for the foreseeable future for simpler debugging during development. -#### [4. The CIBA flow](/verify/getting-started/oidc-intro/#authenticate-with-ciba) +#### [4. The CIBA flow](/verify/how-it-works/oidc-intro/#authenticate-with-ciba) The CIBA flow is designed for use cases where the client application isn't directly operated by the end-user but can trigger the authentication process on their behalf. A canonical example is a call center agent verifying a caller's identity. -#### [5. The Headless flow](/verify/getting-started/oidc-intro/#authenticate-with-headless) +#### [5. The Headless flow](/verify/how-it-works/oidc-intro/#authenticate-with-headless) The Headless flow is a custom protocol by Idura. It allows interacting with eIDs that offer a poll-based workflow, where a user agent redirect is not required. @@ -49,7 +49,7 @@ To begin the login flow, you will need to authenticate the user at the [eID Prov To authenticate the user, your app must send the user to the _OAuth2 authorization endpoint (`/oauth2/authorize`)_ with the appropriate set of parameters. -You can find the URL for the _OAuth2 authorization endpoint_ in the OpenID Connect Discovery Document exposed on your [Idura Verify Domain](/verify/getting-started/basics/#domains): +You can find the URL for the _OAuth2 authorization endpoint_ in the OpenID Connect Discovery Document exposed on your [Idura Verify Domain](/verify/how-it-works/core-concepts/#domains): ```http GET https://YOUR_SUBDOMAIN.idura.broker/.well-known/openid-configuration @@ -188,21 +188,21 @@ When adding login to your application, you will build the authorization URL (als You can try the above URL right now if you have a [test user for Norwegian BankID](/verify/e-ids/norwegian-bankid/#test-users). -Your next steps will depend on the [OpenID Connect flow type](/verify/getting-started/oidc-intro/#supported-openid-connect-flows) you're implementing. See the relevant section below for a description of how each flow unfolds: +Your next steps will depend on the [OpenID Connect flow type](/verify/how-it-works/oidc-intro/#supported-openid-connect-flows) you're implementing. See the relevant section below for a description of how each flow unfolds: -- [Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) -- [PKCE Flow](/verify/getting-started/oidc-intro/#authenticate-with-pkce) -- [Implicit Flow](/verify/getting-started/oidc-intro/#authenticate-with-implicit-flow) -- [CIBA](/verify/getting-started/oidc-intro/#authenticate-with-ciba) -- [Headless](/verify/getting-started/oidc-intro/#authenticate-headless) +- [Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) +- [PKCE Flow](/verify/how-it-works/oidc-intro/#authenticate-with-pkce) +- [Implicit Flow](/verify/how-it-works/oidc-intro/#authenticate-with-implicit-flow) +- [CIBA](/verify/how-it-works/oidc-intro/#authenticate-with-ciba) +- [Headless](/verify/how-it-works/oidc-intro/#authenticate-headless) -After completing the steps specific to your chosen flow, you can proceed to [validating the JWT](/verify/getting-started/oidc-intro/#validate-the-jwt) received from successful authentication. +After completing the steps specific to your chosen flow, you can proceed to [validating the JWT](/verify/how-it-works/oidc-intro/#validate-the-jwt) received from successful authentication. A more secure alternative to traditional authorization requests is [Pushed Authorization Requests (PAR)](/verify/guides/pushed-authorization-requests). -PAR lets you initiate the authentication flow by sending [authorization request parameters](/verify/getting-started/oidc-intro/#authorize-request-parameters) directly to the authorization server via a POST request. +PAR lets you initiate the authentication flow by sending [authorization request parameters](/verify/how-it-works/oidc-intro/#authorize-request-parameters) directly to the authorization server via a POST request. This approach keeps parameters out of URLs, making requests more secure and protecting their integrity. It also ensures sensitive data remains confidential – e.g. if you are including PII in a `login_hint`. [View the PAR implementation guide →](/verify/guides/pushed-authorization-requests/#implementing-par-with-idura) @@ -508,7 +508,7 @@ The validation step is required; without it, you cannot trust the contained end- We strongly recommend that you find a battle-hardened library for your specific platform to do this heavy lifting. You can find an extensive list of libraries on jwt.io. Alternatively, Idura provides a list of [integrations](/verify/integrations) that handle most of the authentication process, including JWT validation. -For more information, see [OpenID Connect security best practices](/verify/getting-started/best-security-practices/#always-validating-id-tokens) and JWT validation guide. +For more information, see [OpenID Connect security best practices](/verify/how-it-works/best-security-practices/#always-validating-id-tokens) and JWT validation guide. ## The 'scope' parameter diff --git a/src/pages/verify/getting-started/overview.mdx b/src/pages/verify/how-it-works/overview.mdx similarity index 94% rename from src/pages/verify/getting-started/overview.mdx rename to src/pages/verify/how-it-works/overview.mdx index 821fa791..d0ab08e5 100644 --- a/src/pages/verify/getting-started/overview.mdx +++ b/src/pages/verify/how-it-works/overview.mdx @@ -1,6 +1,6 @@ --- product: verify -category: Getting Started +category: How it works sort: 0 title: Idura Verify Overview --- @@ -11,11 +11,11 @@ Idura Verify provides eID authentication as a service. An **eID** is a special kind of online identity that is tied to a _natural person_. A natural person in relation to eID is a living, individual human being. Examples of eIDs are Danish MitID, Swedish BankID, and Dutch iDIN. -An eID may be used for authentication and in most cases also for digitally signing legal documents. +An eID may be used for authentication and, in most cases, for digitally signing legal documents. -An eID is different from traditional external identity sources such as Google or Facebook. Generally an online identity lifecycle has three main phases: +An eID is different from traditional external identity sources such as Google or Facebook. Generally, an online identity lifecycle has three main phases: 1. **Enrollment** consists of verification of the legal identity and subsequently the issuance of a digital identity. 2. **Active, day-to-day use** is the authentication of the user as the holder of the issued digital identity. diff --git a/src/pages/verify/index.mdx b/src/pages/verify/index.mdx index be45f92b..d8b029a2 100644 --- a/src/pages/verify/index.mdx +++ b/src/pages/verify/index.mdx @@ -1,23 +1,12 @@ ---- -product: verify -title: Use eID in your applications ---- +export const VerifyRedirect = () => { + const { useEffect } = require('react'); + const { navigate } = require('gatsby'); -For an introduction to Idura Verify and eID, you may want to read [the overview](/verify/getting-started/overview) in the Getting Started section. +useEffect(() => { +navigate('/verify/getting-started', { replace: true }); +}, []); -Idura Verify supports two distinct use cases supported by most eID solutions: +return null; +}; -**Authentication** - -All eID services supports user authentication. With Idura Verify, you integrate using _OpenID Connect_ (aka OIDC). A general introduction to OIDC with Idura Verify is available in the section on [Using OIDC](/verify/getting-started/oidc-intro). - -**Digital Signatures** - -Due to the underlying use of asymmetric encryption by some eID services, like the Norwegian and Swedish BankID, -digitally signing text is also supported through a proprietary Idura API. - -- SE BankID: offers signing via [specific OIDC parameters](/verify/e-ids/swedish-bankid/#signing-textmarkdown) -- NO BankID: More documentation on this will soon follow, - but we have an example of how to program both plain [text signing and PDF signing into your ASP.NET Core app](https://github.com/criipto/docs-old/blob/master/signatures/dotnet-core-v3.md#plain-text-signature) - -If you do not find the documentation you need, please do not hesitate to drop us a note at [support@idura.eu](mailto:support@idura.eu). +export default VerifyRedirect; diff --git a/src/pages/verify/integrations/firebase.mdx b/src/pages/verify/integrations/firebase.mdx index 7607992d..f75685dc 100644 --- a/src/pages/verify/integrations/firebase.mdx +++ b/src/pages/verify/integrations/firebase.mdx @@ -43,7 +43,7 @@ Alternatively, you can follow Firebase documentation for [web applications](http Click **Add new provider**, then select **OpenID Connect**. ![OIDC custom provider](./firebase/OIDC-custom-provider.png) 3. You will now enable and define a new OIDC provider using the [information from your Idura Dashboard and the Client Secret you previously saved](#firebase-application-and-oidc-provider-setup). -4. Choose the **Grant type** you intend to use. We recommend choosing **Code flow**. _For more information, see [OpenID Connect best security practices](/verify/getting-started/best-security-practices/#authorization-code-flow)._ +4. Choose the **Grant type** you intend to use. We recommend choosing **Code flow**. _For more information, see [OpenID Connect best security practices](/verify/how-it-works/best-security-practices/#authorization-code-flow)._ 5. Enter a provider name – this is entirely up to you. We used "Idura" in this example. 6. Enter your Idura Application **Client ID** in the **Client ID** field. 7. Enter your Idura domain in the **Issuer (URL)** field (e.g., `https://acme-corp.idura.broker`). diff --git a/src/pages/verify/reference/glossary.mdx b/src/pages/verify/reference/glossary.mdx index d9e33da0..49943ead 100644 --- a/src/pages/verify/reference/glossary.mdx +++ b/src/pages/verify/reference/glossary.mdx @@ -176,10 +176,12 @@ Mobile apps and single-page applications (SPAs) are public clients. As they cann ## R -### Redirect URI (Callback URL) +### Redirect URI -The URL in your application where the user's browser is redirected after authentication is complete (or has failed). -You have to register all redirect URIs in your Idura Application via the Dashboard. +A redirect URI (also known as a **callback URL** or **redirect URL**) is a URL in your [client application](/verify/reference/glossary/#application-client-application) +where the user's browser is redirected after the authentication process has completed. +Following to the [OpenID Connect Core specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest), Idura does not support wildcard redirect URLs, +meaning that you have to register all redirect URIs in your Idura Application via the Dashboard. ### Response Type diff --git a/src/snippets/generate-client-secret.mdx b/src/snippets/generate-client-secret.mdx new file mode 100644 index 00000000..169f6250 --- /dev/null +++ b/src/snippets/generate-client-secret.mdx @@ -0,0 +1,24 @@ + + **Client secrets are for [server-side + applications](/verify/reference/glossary/#confidential-client) only.** If you are building a + Single Page Application or a native mobile app, you cannot securely store a secret. Skip this step + and use **[PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)** instead. + + +1. Go to the **OpenID Connect** section of your Application settings. +2. Toggle on **Enable OAuth2 Code Flow** and click **Save**. + ![Enable OAuth2 Code Flow toggle](./images/oauth2-enable.png) +3. Copy and save the generated **Client Secret**. _Idura only stores the secret as a hashed value, meaning that once you navigate away from this page, + you won't be able to retrieve the raw value again. If you lose your client secret, you will have to generate a new one and update your code._ + ![OAuth2 client secret](./images/oauth2-client-secret.png) + + + +For maximum security in production, we recommend moving away from client secret authentication and replacing it with safer alternatives: + +- **[Private key JWT authentication](/verify/guides/privatekey-jwt/)**: A secure authentication method for traditional web applications based on asymmetric key cryptography. +- **[PKCE (Proof Key for Code Exchange)](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)**: An extension to the Authorization Code flow that eliminates the need for a client secret entirely. + +Learn more in our **[OpenID Connect Best Security Practices](/verify/how-it-works/best-security-practices/)** guide. + + diff --git a/src/snippets/images/oauth2-client-secret.png b/src/snippets/images/oauth2-client-secret.png index 6cba8b5229388bd8c70dac8c924eb2e689799e92..4ce9c04b0d2db2a8e6b9a4dab629aba076a04e29 100644 GIT binary patch literal 74961 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 z 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 literal 49533 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 From 5e5b7944c3d202c0bc65667f692556f8335bc962 Mon Sep 17 00:00:00 2001 From: nmoskaleva Date: Thu, 2 Apr 2026 12:56:48 +0200 Subject: [PATCH 3/4] fixup! Update Verify's "Getting Started" section to improve developer experience. --- src/pages/verify/getting-started/dashboard-setup.mdx | 2 +- src/pages/verify/getting-started/index.mdx | 12 +++++++++--- src/pages/verify/getting-started/production.mdx | 4 +++- src/snippets/generate-client-secret.mdx | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/pages/verify/getting-started/dashboard-setup.mdx b/src/pages/verify/getting-started/dashboard-setup.mdx index 299a48a6..5d27c2f0 100644 --- a/src/pages/verify/getting-started/dashboard-setup.mdx +++ b/src/pages/verify/getting-started/dashboard-setup.mdx @@ -62,4 +62,4 @@ Your dashboard is configured and your API credentials are ready to use. To be able to run test logins, you need to create a test user for the eID(s) you're planning to use. Note that you can't use your real, personal eID in a test environment. -Proceed to [Creating Test Users →](/verify/getting-started/test-users/) +[Create test users →](/verify/getting-started/test-users/) diff --git a/src/pages/verify/getting-started/index.mdx b/src/pages/verify/getting-started/index.mdx index 72f14d3f..a2ba130c 100644 --- a/src/pages/verify/getting-started/index.mdx +++ b/src/pages/verify/getting-started/index.mdx @@ -52,10 +52,16 @@ You can simulate a full authentication flow right from your browser using our de Or build your knowledge first by exploring our resources: - [Understand OpenID Connect →](/verify/how-it-works/oidc-intro/) Learn about the different OpenID Connect flows supported by Idura Verify, authorization request parameters, JWT tokens, and more. -- [Review Security Best Practices →](/verify/how-it-works/best-security-practices/) See guidelines for securing your implementation and choosing the right OIDC flow for your application architecture. +- [Review security best practices →](/verify/how-it-works/best-security-practices/) See guidelines for securing your implementation and choosing the right OIDC flow for your application architecture. -## Step 4: Move to Production +## Step 4: Move to production Once your integration is working locally with test users, it's time to upgrade. -- [Get Ready for Production →](/verify/getting-started/production/) Review our checklist for applying for eIDs you need and going live. +- [Get ready for production →](/verify/getting-started/production/) Review our checklist for applying for eIDs you need and going live. + + + We recommend starting the [application + process](/verify/getting-started/production/#ordering-production-eids) as early as possible. + Approval and certificate issuance can take several business days depending on the eID provider. + diff --git a/src/pages/verify/getting-started/production.mdx b/src/pages/verify/getting-started/production.mdx index 6e117e84..27e77f2a 100644 --- a/src/pages/verify/getting-started/production.mdx +++ b/src/pages/verify/getting-started/production.mdx @@ -28,7 +28,6 @@ Once your integration is working locally with test users, you are ready to move **Ordering eIDs for production** Each eID provider has specific requirements. Use the links below to review the necessary steps for each provider. -_Tip: Start the application process as early as possible. Approval and certificate issuance can take several business days depending on the eID provider._ - [FrejaID](/verify/e-ids/frejaid/#ordering-frejaid) - [Swedish BankID](/verify/e-ids/swedish-bankid/#ordering-swedish-bankid) @@ -39,6 +38,9 @@ _Tip: Start the application process as early as possible. Approval and certifica - [Finnish Trust Network](/verify/e-ids/finnish-trust-network/#ordering-a-production-agreement) - [Dutch iDIN](/verify/e-ids/dutch-idin/#ordering-idin) +**We recommend starting the application process as early as possible. Approval and certificate +issuance can take several business days depending on the eID provider.** + 3. **Set up your production environment.** diff --git a/src/snippets/generate-client-secret.mdx b/src/snippets/generate-client-secret.mdx index 169f6250..3b4b63b4 100644 --- a/src/snippets/generate-client-secret.mdx +++ b/src/snippets/generate-client-secret.mdx @@ -19,6 +19,6 @@ For maximum security in production, we recommend moving away from client secret - **[Private key JWT authentication](/verify/guides/privatekey-jwt/)**: A secure authentication method for traditional web applications based on asymmetric key cryptography. - **[PKCE (Proof Key for Code Exchange)](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)**: An extension to the Authorization Code flow that eliminates the need for a client secret entirely. -Learn more in our **[OpenID Connect Best Security Practices](/verify/how-it-works/best-security-practices/)** guide. +Learn more in our **[OpenID Connect best security practices](/verify/how-it-works/best-security-practices/)** guide. From d1f5d3679e3428161cf5dc3c5b5ff058a4b6c90f Mon Sep 17 00:00:00 2001 From: nmoskaleva Date: Thu, 2 Apr 2026 13:06:40 +0200 Subject: [PATCH 4/4] fixup! fixup! Update Verify's "Getting Started" section to improve developer experience. --- gatsby-node.ts | 86 +++++++------------------------------------------- 1 file changed, 12 insertions(+), 74 deletions(-) diff --git a/gatsby-node.ts b/gatsby-node.ts index e69d8a03..7c7fa6b0 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -210,8 +210,8 @@ export const createPages: GatsbyNode['createPages'] = ({ actions }) => { force: true, }); createRedirect({ - fromPath: '/verify/articles/custom-ui-samples', - toPath: '/verify/reference/samples', + fromPath: '/verify/getting-started/overview/*', + toPath: '/verify/how-it-works/overview/:splat', isPermanent: true, force: true, }); @@ -240,94 +240,32 @@ export const createPages: GatsbyNode['createPages'] = ({ actions }) => { force: true, }); createRedirect({ - fromPath: '/verify/getting-started/overview', - toPath: '/verify/how-it-works/overview', + fromPath: '/verify/getting-started/overview/*', + toPath: '/verify/how-it-works/overview/:splat', isPermanent: true, force: true, }); createRedirect({ - fromPath: '/verify/getting-started/basics', - toPath: '/verify/how-it-works/core-concepts', + fromPath: '/verify/getting-started/basics/*', + toPath: '/verify/how-it-works/core-concepts/:splat', isPermanent: true, force: true, }); createRedirect({ - fromPath: '/verify/getting-started/basics/#tenants', - toPath: '/verify/how-it-works/core-concepts/#tenants', + fromPath: '/verify/getting-started/oidc-intro/*', + toPath: '/verify/how-it-works/oidc-intro/:splat', isPermanent: true, force: true, }); createRedirect({ - fromPath: '/verify/getting-started/basics/#domains', - toPath: '/verify/how-it-works/core-concepts/#domains', + fromPath: '/verify/getting-started/best-security-practices/*', + toPath: '/verify/how-it-works/best-security-practices/:splat', isPermanent: true, force: true, }); createRedirect({ - fromPath: '/verify/getting-started/basics/#bring-your-own-domain', - toPath: '/verify/how-it-works/core-concepts/#bring-your-own-domain', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/basics/#applications', - toPath: '/verify/how-it-works/core-concepts/#applications', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/basics/#eid-providers', - toPath: '/verify/how-it-works/core-concepts/#eid-providers', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/oidc-intro/', - toPath: '/verify/how-it-works/oidc-intro/', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/best-security-practices/', - toPath: '/verify/how-it-works/best-security-practices/', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/best-security-practices/#authorization-code-flow', - toPath: '/verify/how-it-works/best-security-practices/#authorization-code-flow', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: - '/verify/getting-started/best-security-practices/#pushed-authorization-requests/#the-nonce-parameter', - toPath: - '/verify/how-it-works/best-security-practices/#pushed-authorization-requests/#the-nonce-parameter', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/best-security-practices/#the-state-parameter', - toPath: '/verify/how-it-works/best-security-practices/#the-state-parameter', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/best-security-practices/#always-validating-jwts', - toPath: '/verify/how-it-works/best-security-practices/#always-validating-jwts', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/best-security-practices/#client-authentication', - toPath: '/verify/how-it-works/best-security-practices/#client-authentication', - isPermanent: true, - force: true, - }); - createRedirect({ - fromPath: '/verify/getting-started/best-security-practices/#avoid-implicit-flow', - toPath: '/verify/how-it-works/best-security-practices/#avoid-implicit-flow', + fromPath: '/verify/guides/production/*', + toPath: '/verify/getting-started/production/:splat', isPermanent: true, force: true, });