diff --git a/.gitignore b/.gitignore index 71d182e..848d4ac 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,21 @@ node_modules ._* # Ignore IDE specific files -.vscode/ \ No newline at end of file +.vscode/ + +# Ignore worktrees and brainstorm artifacts +.worktrees/ +.superpowers/ +docs/superpowers/ +**/plans/ +*-plan.md +*-plan-*.md +plan-*.md + +# AI assistant / editor local tooling (never commit) +.claude/ +.cursor/ +.cursorrules +CLAUDE.md +AGENTS.md +CODEX.md \ No newline at end of file diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index ab8a0a7..a3984d7 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -1,8 +1,97 @@ import { defineConfig, type HeadConfig } from 'vitepress' import { full as emoji } from 'markdown-it-emoji' import { withMermaid } from 'vitepress-plugin-mermaid' +import { existsSync } from 'node:fs' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' const SITE_URL = 'https://docs.mobileid.ch' +const DOCS_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..') +const RELEASE_NOTES_POST_LAYOUT = 'release-notes-post' +const SUPPORTED_LANGS = ['en', 'de', 'fr', 'it'] as const + +type SupportedLang = typeof SUPPORTED_LANGS[number] + +const HREFLANG_BY_LANG: Record = { + en: 'en', + de: 'de-CH', + fr: 'fr-CH', + it: 'it-CH', +} + +const OG_LOCALE_BY_LANG: Record = { + en: 'en_US', + de: 'de_CH', + fr: 'fr_CH', + it: 'it_CH', +} + +function toAbsoluteUrl(url: string): string { + if (/^https?:\/\//.test(url)) return url + return `${SITE_URL}${url.startsWith('/') ? '' : '/'}${url}` +} + +function getPageLang(pageData: { relativePath: string; frontmatter: Record }): SupportedLang { + const frontmatterLang = pageData.frontmatter.lang + if (SUPPORTED_LANGS.includes(frontmatterLang)) return frontmatterLang + + const langFromPath = pageData.relativePath.match(/\.(de|fr|it|en)\.md$/)?.[1] + if (langFromPath && SUPPORTED_LANGS.includes(langFromPath as SupportedLang)) { + return langFromPath as SupportedLang + } + + return 'en' +} + +function getPagePath(relativePath: string): string { + return relativePath + .replace(/index\.md$/, '') + .replace(/\.md$/, '.html') +} + +function getSourceRelativePath(url: string): string { + const normalizedUrl = url.replace(/^\//, '') + if (!normalizedUrl) return 'index.md' + if (normalizedUrl.endsWith('/')) return `${normalizedUrl}index.md` + return normalizedUrl.replace(/\.html$/, '.md') +} + +function getAlternatePages(relativePath: string) { + const baseRel = relativePath + .replace(/\.md$/, '') + .replace(/\.(de|fr|it|en)$/, '') + + return SUPPORTED_LANGS.flatMap((lang) => { + const candidateRel = lang === 'en' ? `${baseRel}.md` : `${baseRel}.${lang}.md` + if (!existsSync(resolve(DOCS_ROOT, candidateRel))) return [] + + return [{ + lang, + hreflang: HREFLANG_BY_LANG[lang], + ogLocale: OG_LOCALE_BY_LANG[lang], + path: `/${getPagePath(candidateRel)}`, + url: toAbsoluteUrl(`/${getPagePath(candidateRel)}`), + }] + }) +} + +function getFrontmatterKeywords(frontmatter: Record): string[] { + const rawKeywords = frontmatter.keywords + if (Array.isArray(rawKeywords)) { + return rawKeywords + .map((keyword) => String(keyword).trim()) + .filter(Boolean) + } + + if (typeof rawKeywords === 'string') { + return rawKeywords + .split(',') + .map((keyword) => keyword.trim()) + .filter(Boolean) + } + + return [] +} // https://vitepress.dev/reference/site-config export default withMermaid(defineConfig({ @@ -16,6 +105,31 @@ export default withMermaid(defineConfig({ sitemap: { hostname: SITE_URL, + transformItems(items) { + return items + .map((item) => { + const alternates = getAlternatePages(getSourceRelativePath(String(item.url))) + if (alternates.length < 2) return item + + const xDefault = alternates.find((alternate) => alternate.lang === 'en') + + return { + ...item, + links: [ + ...alternates.map((alternate) => ({ + lang: alternate.hreflang, + url: alternate.path, + })), + ...(xDefault + ? [{ + lang: 'x-default', + url: xDefault.path, + }] + : []), + ], + } + }) + }, }, markdown: { @@ -30,29 +144,124 @@ export default withMermaid(defineConfig({ ['link', { rel: 'shortcut icon', href: '/favicon.ico' }], ['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }], ['link', { rel: 'manifest', href: '/site.webmanifest' }], - ['meta', { name: 'robots', content: 'index, follow' }], + ['meta', { name: 'google-site-verification', content: '2x5Mq4fWD8x1K2N_Z9W0za5Bwjb2WGSv0EdXZjtboPQ' }], + ['meta', { name: 'robots', content: 'index, follow, max-image-preview:large' }], ['meta', { property: 'og:site_name', content: 'Mobile ID docs' }], - ['meta', { property: 'og:type', content: 'website' }], - ['meta', { property: 'og:locale', content: 'en' }], ['meta', { name: 'twitter:card', content: 'summary' }], ], transformPageData(pageData) { - const pagePath = pageData.relativePath - .replace(/index\.md$/, '') - .replace(/\.md$/, '.html') + const pagePath = getPagePath(pageData.relativePath) const canonicalUrl = `${SITE_URL}/${pagePath}` + const lang = getPageLang(pageData) + const alternates = getAlternatePages(pageData.relativePath) const ogTitle = pageData.title || 'Mobile ID docs' const ogDesc = pageData.description || 'Technical documentation for Mobile ID integration' - - pageData.frontmatter.head ??= [] - pageData.frontmatter.head.push( + const socialImage = pageData.frontmatter.thumbnail + ? toAbsoluteUrl(pageData.frontmatter.thumbnail) + : undefined + const isReleaseNotesPost = pageData.frontmatter.layout === RELEASE_NOTES_POST_LAYOUT + const keywords = getFrontmatterKeywords(pageData.frontmatter) + const head: HeadConfig[] = [ ['link', { rel: 'canonical', href: canonicalUrl }], ['meta', { property: 'og:title', content: ogTitle }], ['meta', { property: 'og:description', content: ogDesc }], ['meta', { property: 'og:url', content: canonicalUrl }], - ) + ['meta', { property: 'og:type', content: isReleaseNotesPost ? 'article' : 'website' }], + ['meta', { property: 'og:locale', content: OG_LOCALE_BY_LANG[lang] }], + ] + + if (socialImage) { + head.push( + ['meta', { property: 'og:image', content: socialImage }], + ['meta', { property: 'og:image:alt', content: ogTitle }], + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:image', content: socialImage }], + ) + } + + if (isReleaseNotesPost) { + const publishedDate = pageData.frontmatter.date + ? new Date(pageData.frontmatter.date).toISOString() + : undefined + + head.push( + ['meta', { name: 'twitter:title', content: ogTitle }], + ['meta', { name: 'twitter:description', content: ogDesc }], + ) + + if (publishedDate) { + head.push(['meta', { property: 'article:published_time', content: publishedDate }]) + } + + if (pageData.frontmatter.author) { + head.push(['meta', { property: 'article:author', content: pageData.frontmatter.author }]) + } + + head.push(['meta', { property: 'article:section', content: 'Release Notes' }]) + + if (keywords.length > 0) { + head.push(['meta', { name: 'keywords', content: keywords.join(', ') }]) + + for (const keyword of keywords) { + head.push(['meta', { property: 'article:tag', content: keyword }]) + } + } + + if (alternates.length > 1) { + const currentAlternate = alternates.find((alternate) => alternate.lang === lang) + const xDefault = alternates.find((alternate) => alternate.lang === 'en') ?? currentAlternate + + for (const alternate of alternates) { + head.push(['link', { rel: 'alternate', hreflang: alternate.hreflang, href: alternate.url }]) + } + + if (xDefault) { + head.push(['link', { rel: 'alternate', hreflang: 'x-default', href: xDefault.url }]) + } + + for (const alternate of alternates) { + if (alternate.lang !== lang) { + head.push(['meta', { property: 'og:locale:alternate', content: alternate.ogLocale }]) + } + } + } + + const articleSchema = { + '@context': 'https://schema.org', + '@type': 'BlogPosting', + headline: ogTitle, + description: ogDesc, + url: canonicalUrl, + mainEntityOfPage: canonicalUrl, + datePublished: publishedDate, + inLanguage: HREFLANG_BY_LANG[lang], + articleSection: 'Release Notes', + keywords: keywords.length > 0 ? keywords : undefined, + image: socialImage ? [socialImage] : undefined, + author: pageData.frontmatter.author + ? { + '@type': 'Organization', + name: pageData.frontmatter.author, + } + : undefined, + publisher: { + '@type': 'Organization', + name: 'Swisscom', + url: 'https://www.swisscom.ch/mobileid', + }, + } + + head.push([ + 'script', + { type: 'application/ld+json' }, + JSON.stringify(articleSchema), + ]) + } + + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.push(...head) }, themeConfig: { @@ -64,10 +273,12 @@ export default withMermaid(defineConfig({ { text: 'Home', link: '/' }, { text: 'REST API Guide', link: '/rest-api-guide/introduction' }, { text: 'OIDC Integration Guide', link: '/oidc-integration-guide/introduction' }, - { text: 'RADIUS Gateway Guide', link: '/radius-interface-gateway-guide/introduction' } + { text: 'RADIUS Gateway Guide', link: '/radius-interface-gateway-guide/introduction' }, + { text: 'Release Notes', link: '/release-notes/' }, ], sidebar: { + '/release-notes/': [], '/rest-api-guide/': [ { text: 'REST API Guide', @@ -95,7 +306,10 @@ export default withMermaid(defineConfig({ }, { text: '', - items: [{ text: 'Imprint', link: '/rest-api-guide/imprint' }] + items: [ + { text: 'Imprint', link: '/legal/imprint' }, + { text: 'Privacy Notice', link: '/legal/privacy' } + ] } ], @@ -114,7 +328,10 @@ export default withMermaid(defineConfig({ }, { text: '', - items: [{ text: 'Imprint', link: '/oidc-integration-guide/imprint' }] + items: [ + { text: 'Imprint', link: '/legal/imprint' }, + { text: 'Privacy Notice', link: '/legal/privacy' } + ] } ], @@ -125,13 +342,17 @@ export default withMermaid(defineConfig({ items: [ { text: 'Introduction', link: '/radius-interface-gateway-guide/introduction' }, { text: 'RIG Deployment', link: '/radius-interface-gateway-guide/deployment' }, + { text: 'Configuration', link: '/radius-interface-gateway-guide/configuration' }, { text: 'The RADIUS Protocol', link: '/radius-interface-gateway-guide/radius-protocol' }, { text: 'Annexes', link: '/radius-interface-gateway-guide/annexes' } ] }, { text: '', - items: [{ text: 'Imprint', link: '/radius-interface-gateway-guide/imprint' }] + items: [ + { text: 'Imprint', link: '/legal/imprint' }, + { text: 'Privacy Notice', link: '/legal/privacy' } + ] } ] diff --git a/docs/.vitepress/theme/ReleaseNotesLayout.vue b/docs/.vitepress/theme/ReleaseNotesLayout.vue new file mode 100644 index 0000000..9cc6253 --- /dev/null +++ b/docs/.vitepress/theme/ReleaseNotesLayout.vue @@ -0,0 +1,50 @@ + + + diff --git a/docs/.vitepress/theme/ReleaseNotesPostLayout.vue b/docs/.vitepress/theme/ReleaseNotesPostLayout.vue new file mode 100644 index 0000000..f0284fa --- /dev/null +++ b/docs/.vitepress/theme/ReleaseNotesPostLayout.vue @@ -0,0 +1,46 @@ + + + diff --git a/docs/.vitepress/theme/components/AcrLevels.vue b/docs/.vitepress/theme/components/AcrLevels.vue new file mode 100644 index 0000000..7175346 --- /dev/null +++ b/docs/.vitepress/theme/components/AcrLevels.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/docs/.vitepress/theme/components/AudioPlayer.vue b/docs/.vitepress/theme/components/AudioPlayer.vue new file mode 100644 index 0000000..6513294 --- /dev/null +++ b/docs/.vitepress/theme/components/AudioPlayer.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/docs/.vitepress/theme/components/ComparisonTable.vue b/docs/.vitepress/theme/components/ComparisonTable.vue new file mode 100644 index 0000000..8c52291 --- /dev/null +++ b/docs/.vitepress/theme/components/ComparisonTable.vue @@ -0,0 +1,141 @@ + + + + + diff --git a/docs/.vitepress/theme/components/EntraIntegrationFlow.vue b/docs/.vitepress/theme/components/EntraIntegrationFlow.vue new file mode 100644 index 0000000..1967d6c --- /dev/null +++ b/docs/.vitepress/theme/components/EntraIntegrationFlow.vue @@ -0,0 +1,204 @@ + + + + + diff --git a/docs/.vitepress/theme/components/EntraMigrationTimeline.vue b/docs/.vitepress/theme/components/EntraMigrationTimeline.vue new file mode 100644 index 0000000..c2b0ec4 --- /dev/null +++ b/docs/.vitepress/theme/components/EntraMigrationTimeline.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/docs/.vitepress/theme/components/EntraUseCaseCards.vue b/docs/.vitepress/theme/components/EntraUseCaseCards.vue new file mode 100644 index 0000000..c0f8a5d --- /dev/null +++ b/docs/.vitepress/theme/components/EntraUseCaseCards.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/docs/.vitepress/theme/components/HybridAuthComparisonTable.vue b/docs/.vitepress/theme/components/HybridAuthComparisonTable.vue new file mode 100644 index 0000000..2a76d2f --- /dev/null +++ b/docs/.vitepress/theme/components/HybridAuthComparisonTable.vue @@ -0,0 +1,375 @@ + + + + + diff --git a/docs/.vitepress/theme/components/HybridAuthFlow.vue b/docs/.vitepress/theme/components/HybridAuthFlow.vue new file mode 100644 index 0000000..2bdd1d2 --- /dev/null +++ b/docs/.vitepress/theme/components/HybridAuthFlow.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/docs/.vitepress/theme/components/LanguageSwitcher.vue b/docs/.vitepress/theme/components/LanguageSwitcher.vue new file mode 100644 index 0000000..3c34a1f --- /dev/null +++ b/docs/.vitepress/theme/components/LanguageSwitcher.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/docs/.vitepress/theme/components/LegalFooter.vue b/docs/.vitepress/theme/components/LegalFooter.vue new file mode 100644 index 0000000..968572e --- /dev/null +++ b/docs/.vitepress/theme/components/LegalFooter.vue @@ -0,0 +1,9 @@ + diff --git a/docs/.vitepress/theme/components/PasskeyLoginFlow.vue b/docs/.vitepress/theme/components/PasskeyLoginFlow.vue new file mode 100644 index 0000000..8b0a708 --- /dev/null +++ b/docs/.vitepress/theme/components/PasskeyLoginFlow.vue @@ -0,0 +1,250 @@ + + + + + diff --git a/docs/.vitepress/theme/components/PasskeyRegistrationFlow.vue b/docs/.vitepress/theme/components/PasskeyRegistrationFlow.vue new file mode 100644 index 0000000..942b31c --- /dev/null +++ b/docs/.vitepress/theme/components/PasskeyRegistrationFlow.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/docs/.vitepress/theme/components/PasskeyTypesCards.vue b/docs/.vitepress/theme/components/PasskeyTypesCards.vue new file mode 100644 index 0000000..9ae944e --- /dev/null +++ b/docs/.vitepress/theme/components/PasskeyTypesCards.vue @@ -0,0 +1,191 @@ + + + + + diff --git a/docs/.vitepress/theme/components/ReleaseNotesSidebar.vue b/docs/.vitepress/theme/components/ReleaseNotesSidebar.vue new file mode 100644 index 0000000..1ba2fc8 --- /dev/null +++ b/docs/.vitepress/theme/components/ReleaseNotesSidebar.vue @@ -0,0 +1,65 @@ + + + diff --git a/docs/.vitepress/theme/components/ScreenshotStep.vue b/docs/.vitepress/theme/components/ScreenshotStep.vue new file mode 100644 index 0000000..91154a3 --- /dev/null +++ b/docs/.vitepress/theme/components/ScreenshotStep.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/docs/.vitepress/theme/components/VideoEmbed.vue b/docs/.vitepress/theme/components/VideoEmbed.vue new file mode 100644 index 0000000..b25308d --- /dev/null +++ b/docs/.vitepress/theme/components/VideoEmbed.vue @@ -0,0 +1,46 @@ + + + diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css index fc58530..ef818bd 100644 --- a/docs/.vitepress/theme/custom.css +++ b/docs/.vitepress/theme/custom.css @@ -93,6 +93,10 @@ html.dark img.feature-icon-network { content: url("/img/icon-network-light.svg"); } +html.dark img.feature-icon-megaphone { + content: url("/img/icon-megaphone-light.svg"); +} + /* Or for more specific control */ .VPContent.VPContent.is-home { diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js index e42bd7c..8a34dcd 100644 --- a/docs/.vitepress/theme/index.js +++ b/docs/.vitepress/theme/index.js @@ -6,16 +6,24 @@ import { theme as openApiTheme, useOpenapi } from 'vitepress-openapi/client' import 'vitepress-openapi/dist/style.css' import specYaml from '../../public/openapi-mobileid.yaml?raw' import DocFeedback from './DocFeedback.vue' +import ReleaseNotesLayout from './ReleaseNotesLayout.vue' +import ReleaseNotesPostLayout from './ReleaseNotesPostLayout.vue' import './custom.css' +import './release-notes.css' export default { extends: DefaultTheme, Layout() { - return h(DefaultTheme.Layout, null, { - 'doc-after': () => h(DocFeedback), + return h({ + setup: () => () => h(DefaultTheme.Layout, null, { + 'doc-after': () => h(DocFeedback), + }), }) }, async enhanceApp({ app }) { + app.component('release-notes-index', ReleaseNotesLayout) + app.component('release-notes-post', ReleaseNotesPostLayout) + useOpenapi({ spec: specYaml, config: { @@ -41,7 +49,9 @@ export default { watch( () => route.path, - () => nextTick(() => initZoom()) + () => nextTick(() => { + initZoom() + }) ) } } diff --git a/docs/.vitepress/theme/release-notes.css b/docs/.vitepress/theme/release-notes.css new file mode 100644 index 0000000..94e22c5 --- /dev/null +++ b/docs/.vitepress/theme/release-notes.css @@ -0,0 +1,434 @@ +/* Release Notes — integrated with VitePress docs theme + ==================================================== + Structural styles for the release-notes index and post layouts, + plus utility classes used inside release-notes markdown content. */ + +/* =================================================================== + INDEX PAGE + =================================================================== */ + +.rn-index { + max-width: 860px; + margin: 0 auto; + padding: 48px 32px 32px; +} + +.rn-index-header { + margin-bottom: 32px; +} + +.rn-index-header h1 { + font-family: var(--vp-font-family-heading); + font-size: 2rem; + font-weight: 600; + line-height: 1.25; + letter-spacing: -0.02em; + color: var(--vp-c-text-1); + margin: 0 0 8px; +} + +.rn-index-header p { + font-size: 1rem; + color: var(--vp-c-text-2); + margin: 0; +} + +/* =================================================================== + CARD FEED + =================================================================== */ + +.rn-feed { + display: flex; + flex-direction: column; + gap: 20px; +} + +.rn-card { + display: block; + text-decoration: none; + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + overflow: hidden; + background: var(--vp-c-bg-elv); + transition: border-color 0.25s, box-shadow 0.25s; +} + +.rn-card:hover { + border-color: var(--vp-c-brand-3); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06); +} + +.dark .rn-card:hover { + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3); +} + +.rn-card-thumb { + height: 180px; + overflow: hidden; + background: var(--vp-c-bg-soft); +} + +.rn-card-thumb img { + width: 100%; + height: 100%; + object-fit: cover; +} + +.rn-card-body { + padding: 20px 24px 24px; +} + +.rn-card-meta { + font-size: 0.8rem; + color: var(--vp-c-text-3); + margin-bottom: 8px; +} + +.rn-card-body h2 { + font-family: var(--vp-font-family-heading); + font-size: 1.2rem; + font-weight: 600; + line-height: 1.35; + color: var(--vp-c-text-1); + margin: 0 0 8px; +} + +.rn-card-body p { + font-size: 0.9rem; + color: var(--vp-c-text-2); + line-height: 1.6; + margin: 0 0 14px; +} + +.rn-card-cta { + font-size: 0.88rem; + font-weight: 500; + color: var(--vp-c-brand-3); +} + +/* =================================================================== + POST LAYOUT + =================================================================== */ + +.rn-post-layout { + padding: 32px 24px 0; +} + +.rn-article { + padding: 0 0 48px; +} + +.rn-post-header { + margin-bottom: 24px; + padding-bottom: 20px; + border-bottom: 1px solid var(--vp-c-divider); +} + +.rn-post-header h1 { + margin: 0; + letter-spacing: -0.02em; +} + +.rn-post-meta { + font-size: 0.85rem; + color: var(--vp-c-text-3); + margin: 0 0 12px; + font-weight: 400; +} + +/* =================================================================== + SIDEBAR (matches VitePress sidebar visual language) + =================================================================== */ + +.rn-sidebar { + margin-bottom: 24px; +} + +.rn-sidebar-group { + margin-bottom: 20px; +} + +.rn-sidebar-title { + font-family: var(--vp-font-family-heading); + font-size: 0.85rem; + font-weight: 700; + color: var(--vp-c-text-1); + margin: 0 0 8px; + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.rn-sidebar-nav { + border-left: 1px solid var(--vp-c-divider); + padding-left: 16px; +} + +.rn-sidebar-link { + position: relative; + display: block; + padding: 4px 0; + color: var(--vp-c-text-2); + font-size: 0.88rem; + font-weight: 400; + line-height: 1.5; + text-decoration: none; + transition: color 0.15s; +} + +.rn-sidebar-nav .rn-sidebar-link::before { + content: ''; + position: absolute; + top: 6px; + bottom: 6px; + left: -17px; + width: 2px; + border-radius: 2px; + background: transparent; + transition: background-color 0.15s; +} + +.rn-sidebar-link:hover { + color: var(--vp-c-text-1); +} + +.rn-sidebar-link.is-active { + color: #004844; + font-weight: 600; +} + +html.dark .rn-sidebar-link.is-active { + color: #2dd4b0; +} + +.rn-sidebar-nav .rn-sidebar-link.is-active::before { + background: #004844; +} + +html.dark .rn-sidebar-nav .rn-sidebar-link.is-active::before { + background: #2dd4b0; +} + +.rn-sidebar-legal { + margin-top: 16px; + padding-top: 16px; + border-top: 1px solid var(--vp-c-divider); +} + +.rn-sidebar-legal .rn-sidebar-link { + font-size: 0.82rem; + color: var(--vp-c-text-3); +} + +.rn-sidebar-legal .rn-sidebar-link:hover { + color: var(--vp-c-text-2); +} + +/* Desktop: sidebar + content grid + Pull layout into VPContent's padding-left area so the custom sidebar + occupies the same space as VitePress's VPSidebar and article content + aligns with regular doc pages (VPDoc padding: 48px 32px 0). */ +@media (min-width: 960px) { + .rn-post-layout { + max-width: 1152px; + margin: 0 auto; + display: grid; + grid-template-columns: 240px minmax(0, 1fr); + gap: 48px; + align-items: start; + padding: 48px 32px 0; + } + + .rn-sidebar { + position: sticky; + top: calc(var(--vp-nav-height) + 32px); + margin: 0; + padding: 0; + } + + .rn-article { + min-width: 0; + max-width: 864px; + padding: 0 0 48px; + } +} + +/* Mobile */ +@media (max-width: 959px) { + .rn-index { + padding: 32px 16px 24px; + } + + .rn-post-layout { + padding: 24px 16px 0; + } +} + +/* =================================================================== + FOOTER (minimal legal links on index page) + =================================================================== */ + +.rn-footer { + margin-top: 40px; + padding-top: 20px; + border-top: 1px solid var(--vp-c-divider); + font-size: 0.82rem; + color: var(--vp-c-text-3); + display: flex; + gap: 8px; + align-items: center; +} + +.rn-footer a { + color: var(--vp-c-text-3); + text-decoration: none; + transition: color 0.15s; +} + +.rn-footer a:hover { + color: var(--vp-c-text-2); +} + +/* =================================================================== + CONTENT UTILITIES (used in markdown of release-notes posts) + =================================================================== */ + +/* Lead paragraph */ +.blog-lead { + font-size: 1.05rem; + font-weight: 500; + border-left: 3px solid var(--vp-c-brand-3); + padding-left: 16px; + margin-bottom: 2em; + color: var(--vp-c-text-1); + line-height: 1.7; +} + +/* Full-width breakout from content column */ +.blog-wide { + margin-left: -24px; + margin-right: -24px; +} + +@media (max-width: 959px) { + .blog-wide { + margin-left: -16px; + margin-right: -16px; + } +} + +/* Infographic image */ +.blog-infographic { + border-radius: 12px; + overflow: hidden; + margin: 1.5em 0; + background: var(--vp-c-bg-soft); +} + +.blog-infographic img { + width: 100%; + height: auto; + display: block; +} + +/* Video embed */ +.blog-video { + margin: 2em 0; + border-radius: 12px; + overflow: hidden; + background: var(--vp-c-bg-soft); + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); +} + +.dark .blog-video { + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25); +} + +.blog-video video { + width: 100%; + height: auto; + display: block; +} + +.blog-video-caption { + padding: 0.75em 1.25em; + font-size: 0.9em; + color: var(--vp-c-text-2); + display: flex; + align-items: center; + gap: 0.5em; +} + +.blog-video-caption .video-icon { + flex-shrink: 0; + width: 18px; + height: 18px; + opacity: 0.6; +} + +/* Step list blocks */ +.blog-step-list { + display: grid; + gap: 14px; + margin: 1.4em 0 1.8em; +} + +.blog-step-card { + display: grid; + grid-template-columns: 40px minmax(0, 1fr); + gap: 14px; + align-items: flex-start; + padding: 16px 18px; + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + background: var(--vp-c-bg-soft); +} + +.blog-step-number { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 999px; + background: #004844; + color: #fff; + font-family: var(--vp-font-family-heading); + font-size: 1rem; + font-weight: 600; + line-height: 1; +} + +.dark .blog-step-number { + background: #2dd4b0; + color: #1b1b1f; +} + +.blog-step-body p:last-child { + margin-bottom: 0; +} + +.blog-step-title { + display: block; + margin-bottom: 0.25em; + font-family: var(--vp-font-family-heading); + font-size: 1rem; + font-weight: 600; + line-height: 1.35; + color: var(--vp-c-text-1); +} + +@media (max-width: 640px) { + .blog-step-card { + grid-template-columns: 34px minmax(0, 1fr); + gap: 12px; + padding: 14px; + } + + .blog-step-number { + width: 34px; + height: 34px; + font-size: 0.95rem; + } +} + +/* Language switcher styles are scoped inside LanguageSwitcher.vue */ diff --git a/docs/.vitepress/theme/release-notes.data.mts b/docs/.vitepress/theme/release-notes.data.mts new file mode 100644 index 0000000..16abe46 --- /dev/null +++ b/docs/.vitepress/theme/release-notes.data.mts @@ -0,0 +1,28 @@ +import { createContentLoader } from 'vitepress' + +export interface ReleaseNotesPost { + url: string + title: string + date: string + description: string + thumbnail: string + readingTime: number + author: string +} + +export default createContentLoader('release-notes/posts/*.md', { + transform(raw): ReleaseNotesPost[] { + return raw + .filter(({ url }) => !/\.\w{2}\.html$/.test(url)) + .sort((a, b) => +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)) + .map(({ url, frontmatter }) => ({ + url, + title: frontmatter.title ?? '', + date: frontmatter.date ?? '', + description: frontmatter.description ?? '', + thumbnail: frontmatter.thumbnail ?? '', + readingTime: frontmatter.readingTime ?? 0, + author: frontmatter.author ?? '', + })) + }, +}) diff --git a/docs/.vitepress/theme/release-notes.sidebar.data.mts b/docs/.vitepress/theme/release-notes.sidebar.data.mts new file mode 100644 index 0000000..3867198 --- /dev/null +++ b/docs/.vitepress/theme/release-notes.sidebar.data.mts @@ -0,0 +1,32 @@ +import { createContentLoader } from 'vitepress' + +export interface ReleaseNotesSidebarPost { + url: string + baseUrl: string + title: string + date: string + lang: string +} + +function getLang(url: string, frontmatterLang: unknown): string { + if (typeof frontmatterLang === 'string' && frontmatterLang) return frontmatterLang + return url.match(/\.(de|fr|it)\.html$/)?.[1] ?? 'en' +} + +function getBaseUrl(url: string): string { + return url.replace(/\.(de|fr|it)\.html$/, '.html') +} + +export default createContentLoader('release-notes/posts/*.md', { + transform(raw): ReleaseNotesSidebarPost[] { + return raw + .map(({ url, frontmatter }) => ({ + url, + baseUrl: getBaseUrl(url), + title: frontmatter.title ?? '', + date: frontmatter.date ?? '', + lang: getLang(url, frontmatter.lang), + })) + .sort((a, b) => +new Date(b.date) - +new Date(a.date)) + }, +}) diff --git a/docs/index.md b/docs/index.md index 43d0832..51e3cd5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,6 +28,12 @@ features: class: feature-icon-network details: Start here to integrate Mobile ID strong authentication into your existing RADIUS-based network via the RADIUS Interface Gateway (RIG). link: /radius-interface-gateway-guide/introduction + - title: Release Notes + icon: + src: /img/icon-megaphone.svg + class: feature-icon-megaphone + details: Stay up to date with the latest Mobile ID features, enhancements, and in-depth articles on authentication capabilities. + link: /release-notes/ ---
diff --git a/docs/legal/imprint.md b/docs/legal/imprint.md new file mode 100644 index 0000000..98030db --- /dev/null +++ b/docs/legal/imprint.md @@ -0,0 +1,30 @@ +# Imprint + +`docs.mobileid.ch` is operated for the Mobile ID brand by Swisscom. + +## Provider + +Swisscom (Switzerland) Ltd +Head office: Ittigen + +Postal address: +Swisscom (Switzerland) Ltd +Alte Tiefenaustrasse 6 +CH-3050 Bern +Switzerland + +## Contact + +For questions about `docs.mobileid.ch` and Mobile ID integrations: + +- E-mail: [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com) + +For general information about the Mobile ID service: + +- Website: [mobileid.ch](https://www.mobileid.ch/en) + +## Data protection + +The privacy notice for `docs.mobileid.ch` is available here: + +- [Privacy Notice](/legal/privacy) diff --git a/docs/legal/privacy.md b/docs/legal/privacy.md new file mode 100644 index 0000000..837d350 --- /dev/null +++ b/docs/legal/privacy.md @@ -0,0 +1,69 @@ +# Privacy Notice + +This privacy notice applies to the use of `docs.mobileid.ch`. + +## Controller + +Swisscom (Switzerland) Ltd +Alte Tiefenaustrasse 6 +CH-3050 Bern +Switzerland + +For questions about this documentation website: + +- E-mail: [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com) + +For data protection requests relating to Swisscom: + +- E-mail: [datenschutz@swisscom.com](mailto:datenschutz@swisscom.com) + +Additional general information about privacy at Swisscom is available here: + +- [Swisscom privacy information](https://www.swisscom.ch/en/about/privacy.html) + +## What data may be processed + +When you visit `docs.mobileid.ch`, technical data required to deliver and secure the website may be processed, including in particular: + +- IP address +- date and time of the request +- requested URL and transferred content +- referrer URL +- browser, operating system and device information + +If you contact us by e-mail, we also process the information you send us. + +## Purposes + +We process these data to: + +- provide the documentation website +- ensure the security, stability and integrity of the service +- investigate misuse, faults and incidents +- answer inquiries sent to us + +## Hosting and recipients + +`docs.mobileid.ch` is delivered using GitHub Pages and related delivery infrastructure. In this context, GitHub may process technical connection and log data on behalf of website delivery. + +At the time of writing, this documentation website does not use separate analytics or marketing trackers. The site stores the selected light or dark appearance locally in your browser to remember your preference. + +## International transfers + +When GitHub Pages or related infrastructure are used, personal data may also be processed outside Switzerland, including in the United States. + +GitHub states that it participates in the Swiss-U.S. Data Privacy Framework. Further information is available in the GitHub privacy statement: + +- [GitHub General Privacy Statement](https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement) + +## Your rights + +Under applicable law, you may have rights to information, access, rectification, erasure or objection, depending on the specific circumstances. + +To exercise such rights or ask privacy-related questions, contact: + +- [datenschutz@swisscom.com](mailto:datenschutz@swisscom.com) + +## Last updated + +28 March 2026 diff --git a/docs/oidc-integration-guide/cloud-integration-guide.md b/docs/oidc-integration-guide/cloud-integration-guide.md index 01094c5..edef49a 100644 --- a/docs/oidc-integration-guide/cloud-integration-guide.md +++ b/docs/oidc-integration-guide/cloud-integration-guide.md @@ -4,34 +4,48 @@ This chapter covers a few Mobile ID integration scenario examples with popular p ## Microsoft Entra ID -[MobileID](https://www.swisscom.ch/mid) integrates with Microsoft Entra ID as an external authentication method, enabling Multi-Factor-Authentication (MFA) for Entra ID logon. MobileID provides seamless inline user enrolment, self-service device management, and supports a range of authentication methods, including highly secure crypto-SIM tokens and app-based push authentication for iOS and Android, with advanced options such as Number Matching and Geofencing. +[MobileID](https://www.swisscom.ch/mid) integrates with Microsoft Entra ID using External MFA. In this model, Entra ID remains the identity platform and hands the MFA step to MobileID as the external provider. -In 2020, Microsoft announced plans to replace custom controls with a new method for integrating third-party authentication. MobileID has been working closely with Microsoft to deliver an authentication solution for their new Microsoft External Authentication Methods (EAM) framework, available from May 2024. +Within the broader Mobile ID ecosystem, strong user authentication can be fulfilled with **Mobile ID SIM**, **Mobile ID App**, and **Mobile ID Passkeys**. Microsoft Entra ID does not need to understand or configure these internal methods individually. It consumes the successful result of the Mobile ID provider flow. -MobileID via EAM is fully recognized as a multifactor authentication method within Entra ID, meeting MFA policy requirements. Once MobileID is defined as an EAM provider, you can create Entra ID conditional access policies with MFA using MobileID and assign these to specific users, groups, or applications. +In 2020, Microsoft announced plans to replace custom controls with a new method for integrating third-party authentication. MobileID has been working closely with Microsoft to deliver an authentication solution for Microsoft External MFA, previously known as External Authentication Methods (EAM), available from May 2024 and generally available since March 2026. + +MobileID via External MFA can satisfy the standard **Require multifactor authentication** grant control in Entra ID Conditional Access and is managed alongside the other authentication methods in Entra ID. It is not identical to every built-in Entra method, however: Microsoft does not currently support External MFA with Authentication Strengths. ::: info -For more information, check out the [EAM public preview on the Microsoft blog](https://techcommunity.microsoft.com/t5/microsoft-entra-blog/public-preview-external-authentication-methods-in-microsoft/ba-p/4078808). Mobile ID for Entra ID External Authentication Methods is a [Microsoft Early Access feature](https://learn.microsoft.com/en-us/entra/fundamentals/licensing-preview-info). +External MFA in Microsoft Entra ID is now generally available. For the current Microsoft guidance, see the [GA announcement](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/external-mfa-in-microsoft-entra-id-is-now-generally-available/4488926), [How to manage external MFA in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-external-method-manage), and the [Microsoft Entra External MFA method provider reference](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-authentication-external-method-provider). External MFA replaces Custom Controls, which Microsoft plans to deprecate on September 30, 2026. ::: +### How the Entra External MFA Hand-off Works + +Microsoft Entra ID talks to the external provider through the **OIDC implicit-flow pattern documented by Microsoft for External MFA**. In practice, Entra ID sends a request to the MobileID authorization endpoint with parameters such as `response_type=id_token`, `response_mode=form_post`, and an `id_token_hint` that identifies the user and tenant. + +MobileID validates that Entra context, runs the provider-side authentication journey, and returns a signed `id_token` to Entra ID. Entra ID validates the returned claims and decides whether the MFA requirement is satisfied. + +This separation is important for documentation and operations: + +- **Entra ID** decides when MFA is required and consumes the external MFA result. +- **Mobile ID** decides how the user authenticates inside the provider journey. +- Method-specific controls from the standard Mobile ID OIDC integration, such as ACR values or passkey `keyringId` handling, are **not configured in the Entra admin center**. + ### Sign-in Flow ![entraid-sign-in-flow](/img/entraid-sign-in-flow.png) ### Known Limitations -- Users must specifically select the MobileID EAM option during authentication. If they have other MFA methods configured besides MobileID, they may need to click "Other options" on the Microsoft "Verify your identity" prompt in order to choose MobileID. Microsoft plans to introduce system-preferred defaults for EAM in the future, which will automatically prioritize the default method displayed during authentication. -- EAM currently does not support logins for external guest users. -- Cross-tenant user authentication with the MobileID EAM has limitations. It will only work if: +- Users must specifically select the MobileID External MFA option during authentication. If they have other MFA methods configured besides MobileID, they may need to click "Other options" on the Microsoft "Verify your identity" prompt in order to choose MobileID. +- Microsoft Entra ID does not expose Mobile ID-specific method selection. Whether Mobile ID uses SIM, App, or Passkey inside the provider journey depends on the user's activated methods and the Mobile ID provider-side configuration for that Entra integration. +- Cross-tenant user authentication with MobileID External MFA has limitations. It will only work if: - The external Microsoft Entra organization trusts MFA claims from the user's home tenant. - The user has already established a valid MFA claim by authenticating to an application within their home tenant before accessing the cross-tenant application. -- Azure Government does not yet support Entra ID external authentication methods. Be sure to review Microsoft Entra feature availability for Azure Government. The "Microsoft Entra ID: External Authentication Methods" application is not accessible under MobileID Federal plans. +- Azure Government does not yet support Entra ID External MFA. Be sure to review Microsoft Entra feature availability for Azure Government. The "Microsoft Entra ID: External Authentication Methods" application is not accessible under MobileID Federal plans. ### Prerequisites To use MobileID MFA with Microsoft Entra ID, you'll need the following: -- Before you can integrate and use MobileID EAM, the client onboarding process must have been completed by Swisscom. You will need the following information from Swisscom to be able to create an EAM: +- Before you can integrate and use MobileID External MFA, the client onboarding process must have been completed by Swisscom. You will need the following information from Swisscom to be able to create an External MFA method: - An **Application ID** is generally a multitenant application from your provider, which is used as part of the integration. You need to provide admin consent for this application in your tenant. - A **Client ID** is an identifier from your provider used as part of the authentication integration to identify Microsoft Entra ID requesting authentication. - A **Discovery URL** is the OpenID Connect (OIDC) discovery endpoint for the external authentication provider. @@ -41,18 +55,18 @@ If you did not receive this information, it means that your onboarding process i ::: - An active [Entra ID P1 or P2](https://azure.microsoft.com/en-us/pricing/details/active-directory/) subscription with Conditional Access enabled, and P1/P2 licenses assigned to each user who will log in using MobileID MFA. Plans like Microsoft 365 E3, E5, and F3, as well as Enterprise Mobility + Security E3 and E5, and Microsoft Business Premium, all include Entra ID Premium. -- A designated Entra ID admin service account to authorize the MobileID application access. This account requires the Entra ID Global Administrator or Privileged Role Administrator role during the MobileID setup process, though you can reduce the service account's role privileges afterward. +- A designated Entra ID admin account. Configuring the external MFA method and Conditional Access policies requires at least the **Authentication Policy Administrator** role. Granting admin consent for the MobileID application (Step 8 below) requires at least the **Privileged Role Administrator** role. A Global Administrator can perform both steps, but is not the minimum required role for either. You can reduce the account's role privileges after setup is complete. ### Configure Entra ID -Follow these steps to configure MobileID as an external authentication method in Microsoft Entra ID: +Follow these steps to configure MobileID as an External MFA method in Microsoft Entra ID: | Step | Description | |------|-------------| -| 1 | **Log in to Entra ID**

Go to the [Microsoft Entra admin center](https://entra.microsoft.com) and log in to your Entra ID tenant as a global administrator.

If you're using the [Azure portal](https://portal.azure.com), the navigation will differ slightly. | -| 2 | **Navigate to Policies**

In the Entra Admin Center, go to **Protection → Authentication Methods → Policies**.

If you're logged into the Azure portal instead, first select Microsoft Entra ID, then go to **Security → Authentication Methods → Policies**. | -| 3 | **Add External Method**

Click **+ Add External Method**.

![entraid-add-external-method](/img/entraid-add-external-method.png) | -| 4 | **Configure the External Method**

On the "Add external method" page, enter a descriptive name for the MobileID method. The default name might be "Mobile ID" but you can choose a name that will make sense to your users since they'll see this during authentication.

**Note:** You cannot change the name after creation.

Enter the information you have received from Swisscom in the corresponding field: **Client ID**, **Discovery Endpoint**, **App ID**.

![entraid-configure-external-method](/img/entraid-configure-external-method.png) | +| 1 | **Log in to Entra ID**

Go to the [Microsoft Entra admin center](https://entra.microsoft.com) and log in to your Entra ID tenant as at least an Authentication Policy Administrator. For Step 8 (admin consent), you will need at least the Privileged Role Administrator role.

If you're using the [Azure portal](https://portal.azure.com), the navigation will differ slightly. | +| 2 | **Navigate to Authentication Methods**

In the Entra Admin Center, go to **Entra ID → Authentication methods → Add external MFA**.

If you're logged into the Azure portal instead, first select Microsoft Entra ID, then go to **Security → Authentication Methods**. | +| 3 | **Add External MFA**

Click **+ Add External MFA**.

![entraid-add-external-method](/img/entraid-add-external-method.png) | +| 4 | **Configure the External MFA Method**

On the "Add external MFA" page, enter a descriptive name for the MobileID method. The default name might be "Mobile ID" but you can choose a name that will make sense to your users since they'll see this during authentication.

**Note:** You cannot change the name after creation.

Enter the information you have received from Swisscom in the corresponding field: **Client ID**, **Discovery Endpoint**, **App ID**.

![entraid-configure-external-method](/img/entraid-configure-external-method.png) | | 5 | **Enable the Method**

If you want to enable MobileID MFA right away, toggle Enable from "Off" to "On". | | 6 | **Specify Users**

Before saving the new MobileID external method, decide which users should have access to it.

By default, it will apply to all users, meaning any Entra ID user with a Conditional Access Policy requiring multifactor authentication (MFA) will see MobileID as an option.

To apply it to specific users, click **+ Add Target** under the "Include" tab and choose **Select Targets**. On the "Add directory members" page, select one or more Entra ID directory groups that contain the users you want to target for MobileID authentication, then click **Select**. | | 7 | **Save the Configuration**

After entering all the required details, click **Save** to create the new MobileID external method. | @@ -62,7 +76,7 @@ Follow these steps to configure MobileID as an external authentication method in | Step | Description | |------|-------------| -| 1 | **Log in to Entra ID**

Go to the [Microsoft Entra admin center](https://entra.microsoft.com) and log in to your Entra ID tenant as a global administrator.

If you're using the [Azure portal](https://portal.azure.com), the navigation will differ slightly. | +| 1 | **Log in to Entra ID**

Go to the [Microsoft Entra admin center](https://entra.microsoft.com) and log in to your Entra ID tenant as at least an Authentication Policy Administrator.

If you're using the [Azure portal](https://portal.azure.com), the navigation will differ slightly. | | 2 | **Navigate to Conditional Access**

Click on **Conditional Access** in the left-hand menu, then click **+ Create New Policy**.

If you are in the Azure portal, navigate to **Security → Conditional Access → Policies**.

![entraid-conditional-access](/img/entraid-conditional-access.png) | | 3 | **Name the Policy**

Enter a descriptive name for the new policy, such as "MobileID MFA for Acme Users". | | 4 | **Assign the Policy**

You can assign this policy to specific users or groups, Entra ID cloud apps, or other conditions like client platforms or networks.

*Example for assigning to users:* Click **Users** under "Assignments", then select **Users and groups** on the "Include" tab. Choose **Users and groups** and click **0 users and groups selected** to locate the users or Entra ID security groups for whom you want to enforce MobileID MFA. Select the users or groups, then click **Select** to apply your choices.

If you targeted specific groups when creating the MobileID external method, ensure that you apply this new policy to the same groups.

*Example for assigning to resources:* Click **Target resources**. On the "Include" tab, select **Apps**, and choose the Entra ID applications where you want MobileID MFA to be applied. | @@ -87,7 +101,7 @@ If you want users to exclusively use MobileID instead of the Microsoft Authentic Log in to Entra ID using a user account that has been assigned the Conditional Access policy requiring MFA and is a target for the newly created MobileID external method. -If you applied the MobileID Conditional Access policy to "All cloud apps", when you log into the Office portal (e.g., [https://office.com](https://office.com)) and submit your primary Entra ID credentials, you'll see your MobileID external authentication method as an option for identity verification. The name displayed will be the one you entered when setting up the MobileID external method in Entra ID. +If you applied the MobileID Conditional Access policy to "All cloud apps", when you log into the Office portal (e.g., [https://office.com](https://office.com)) and submit your primary Entra ID credentials, you'll see your MobileID External MFA method as an option for identity verification. The name displayed will be the one you entered when setting up the MobileID External MFA method in Entra ID. entraid-verify-identity @@ -97,7 +111,7 @@ If you have multiple Entra ID authentication methods enabled, you may need to cl entraid-other-options -You will be redirected to the MobileID prompt or user enrolment, depending on your configuration. +You will be redirected to the MobileID provider journey, where MobileID either starts user enrolment or prompts for one of the enabled authentication methods, depending on your configuration. Once you complete the MobileID authentication, you'll return to Entra ID to finish logging in to the application. @@ -106,7 +120,7 @@ Once you complete the MobileID authentication, you'll return to Entra ID to fini If your Conditional Access policy requiring MFA is only applied to specific applications, the initial login to the Office portal will not prompt for MobileID MFA. However, accessing the protected application within the Office portal or directly will trigger the MobileID MFA prompt. ::: warning -If you encounter the "Looks like something went wrong" error from Microsoft, the new EAM settings might need additional time to propagate. If the error persists, you may request support from Swisscom. +If you encounter the "Looks like something went wrong" error from Microsoft, the new External MFA settings might need additional time to propagate. If the error persists, you may request support from Swisscom. ::: ### Troubleshooting diff --git a/docs/oidc-integration-guide/imprint.md b/docs/oidc-integration-guide/imprint.md index a2a27bf..1dd1894 100644 --- a/docs/oidc-integration-guide/imprint.md +++ b/docs/oidc-integration-guide/imprint.md @@ -1,11 +1,8 @@ # Imprint -Mobile ID ist eine Marke von Swisscom.
-Swisscom (Schweiz) AG +This legacy page is kept for compatibility with existing guide links. -Sitz: Ittigen +The current legal information for `docs.mobileid.ch` is available here: -Postadresse:
-Swisscom (Schweiz) AG
-Alte Tiefenaustrasse 6
-CH-3050 Bern
\ No newline at end of file +- [Imprint](/legal/imprint) +- [Privacy Notice](/legal/privacy) diff --git a/docs/oidc-integration-guide/introduction.md b/docs/oidc-integration-guide/introduction.md index 2aecac3..2effa46 100644 --- a/docs/oidc-integration-guide/introduction.md +++ b/docs/oidc-integration-guide/introduction.md @@ -33,8 +33,69 @@ The most basic key concepts are as follows. Mobile ID utilizes the **Authorization Code Grant Type** to obtain an access token that allows the application to retrieve user data after authenticating. The Authorization Code Flow, in abstract, follows these steps: -![auth-code-grant-flow](/img/auth-code-grant-flow.png) - +```mermaid +sequenceDiagram + actor EU as End-User + participant UA as User-Agent
(Browser, App) + participant RP as Relying Party
company.ch + participant AuthZ as Mobile ID (OP)
Authorization Endpoint + participant Tok as Mobile ID (OP)
Token Endpoint + participant UI as Mobile ID (OP)
UserInfo Endpoint + + rect rgb(240, 248, 255) + Note over EU, AuthZ: (A) + EU->>UA: User clicks sign-in button at https://company.ch to request access to protected resource + UA->>RP: + Note right of RP: optional parameters are
login_hint, ui_locales,
dtbd, acr_values + RP->>AuthZ: + AuthZ->>UA: Redirect to https://m.mobileid.ch + end + + rect rgb(240, 255, 240) + Note over EU, AuthZ: (B) + UA->>AuthZ: Authentication request : client_id, redirect_uri, scope + AuthZ->>AuthZ: Validate client + AuthZ->>UA: Return sign-in page of https://m.mobileid.ch + UA->>AuthZ: User starts sign-in at https://m.mobileid.ch + AuthZ->>AuthZ: Start Mobile ID authentication & authorization
incl. account recovery, if needed + AuthZ->>EU: Mobile ID authentication request to confirm sign in to protected resource + Note left of EU: Authenticate with
Mobile ID + EU->>AuthZ: Mobile ID authentication response + AuthZ->>AuthZ: Cache authentication data temporarily + EU->>AuthZ: User grants access to user information (authorization step) + end + + rect rgb(255, 248, 240) + Note over UA, AuthZ: (C) + AuthZ->>UA: Redirect to https://company.ch + authorization-code (short lived) + UA->>RP: Authorization-code + end + + rect rgb(240, 240, 255) + Note over RP, Tok: (D) + RP->>Tok: Request access token and ID token using authorization-code + Tok->>Tok: Validate authorization-code + end + + rect rgb(255, 240, 255) + Note over RP, Tok: (E) + Tok->>RP: access token & ID token returned (short-lived) + end + + rect rgb(255, 255, 240) + Note over RP, UI: (F) Optionally to retrieve extra user info + RP->>UI: request user claims using ID token + UI->>UI: Validate token + UI->>RP: claims returned (phone number, location, etc.) + RP->>RP: Validate extra user info + end + + rect rgb(245, 245, 245) + Note over EU, RP: (G) + RP->>UA: Allow or deny access based on access token and optional user info + UA->>EU: User is signed in + end +``` 1. An **End-User** requests access to a protected resource of the Relying Party. For example, the End-User clicks on a sign-in button or launches an app. The Relying Party redirects the User-Agent to the Mobile ID Authorization Endpoint at `https://m.mobileid.ch`. 2. The Mobile ID Authorization Server **authenticates** the End-User (using an appropriate Mobile ID authentication method) and establishes whether the End-User grants or denies the Relying Party Client's access request, including access to extra user information that might have been requested in the scope of the authentication request sent by the Relying Party. diff --git a/docs/oidc-integration-guide/passkey-authentication.md b/docs/oidc-integration-guide/passkey-authentication.md index 72a9a62..592091f 100644 --- a/docs/oidc-integration-guide/passkey-authentication.md +++ b/docs/oidc-integration-guide/passkey-authentication.md @@ -1,11 +1,17 @@ # Passkey Authentication (early access) -::: warning Early Access - Pilot Phase -MobileID Passkeys are currently available to **pilot testers only** and are not yet generally available in the production environment. This documentation is published in advance so Relying Parties can prepare their integration. General availability for all customers and users is expected **very soon**. Check back shortly for updates. +::: warning Early Access +MobileID Passkeys are now live in the production environment as a **freshly launched capability**. We still describe the feature as early access because the rollout is recent and platform compatibility, policy options, and operational guidance may continue to evolve quickly. Check back shortly for updates. ::: MobileID now supports **FIDO2 Passkeys** as an authentication method within the OpenID Connect service. Relying Parties can allow their users to authenticate using MobileID Passkeys - alongside or instead of the existing MobileID SIM, App, and OTP SMS methods. +::: info Scope: standard Mobile ID OIDC vs. Entra External MFA +This page documents the **standard Mobile ID OIDC relying-party integration**, where the RP uses the authorization code flow and can request Mobile ID-specific ACR values, passkey scopes, and `keyringId` handling. + +**Microsoft Entra ID External MFA is a different integration pattern.** In that model, Entra ID calls the external provider with its own OIDC implicit-flow profile and consumes only the provider result. The Entra admin center does not expose these Mobile ID-specific ACR or passkey controls. See [Public Cloud Integration / Microsoft Entra ID](/oidc-integration-guide/cloud-integration-guide#microsoft-entra-id). +::: + ## What Are Passkeys? The MobileID ecosystem already offers several proven authentication methods: **MobileID SIM** (SIM-based authentication), **MobileID App** (push-based authentication on iOS and Android), and **OTP SMS**. With the introduction of **FIDO2 Passkeys**, MobileID now adds a modern, phishing-resistant authentication option to its portfolio - giving Relying Parties and their users even more flexibility to balance security and convenience. diff --git a/docs/public/img/icon-megaphone-light.svg b/docs/public/img/icon-megaphone-light.svg new file mode 100644 index 0000000..f1f84db --- /dev/null +++ b/docs/public/img/icon-megaphone-light.svg @@ -0,0 +1 @@ + diff --git a/docs/public/img/icon-megaphone.svg b/docs/public/img/icon-megaphone.svg new file mode 100644 index 0000000..8ea68f8 --- /dev/null +++ b/docs/public/img/icon-megaphone.svg @@ -0,0 +1 @@ + diff --git a/docs/public/llms-full.txt b/docs/public/llms-full.txt new file mode 100644 index 0000000..49055ac --- /dev/null +++ b/docs/public/llms-full.txt @@ -0,0 +1,7862 @@ +# Mobile ID – Technical Documentation + +> Mobile ID provides seamless strong multi-factor authentication. +> This site contains integration guides for REST API, OpenID Connect (OIDC), +> RADIUS gateway, and Passkey authentication. + + +## Main entry points + +- Homepage + https://docs.mobileid.ch/ + +- REST API Guide + https://docs.mobileid.ch/rest-api-guide/introduction.html + +- OIDC Integration Guide + https://docs.mobileid.ch/oidc-integration-guide/introduction.html + +- RADIUS Gateway Guide + https://docs.mobileid.ch/radius-interface-gateway-guide/introduction.html + + +## REST API Guide + +- Introduction + https://docs.mobileid.ch/rest-api-guide/introduction.html + +- Integration Steps + https://docs.mobileid.ch/rest-api-guide/app-provider-client-integration.html + +- Mobile ID API + https://docs.mobileid.ch/rest-api-guide/mobile-id-api.html + +- Best Practices + https://docs.mobileid.ch/rest-api-guide/best-practices.html + +- Auto Activation + https://docs.mobileid.ch/rest-api-guide/auto-activation.html + +- Status and Fault Codes + https://docs.mobileid.ch/rest-api-guide/status-fault-codes.html + +- Root CA Certificates + https://docs.mobileid.ch/rest-api-guide/root-ca-certs.html + +- Create Client Certificates + https://docs.mobileid.ch/rest-api-guide/create-client-certs.html + +- Health Status Service + https://docs.mobileid.ch/rest-api-guide/health-status.html + +- Java Reference Client + https://docs.mobileid.ch/rest-api-guide/java-reference-client.html + +- Troubleshooting + https://docs.mobileid.ch/rest-api-guide/troubleshooting.html + +- API Specification (OpenAPI / REST) + https://docs.mobileid.ch/rest-api-guide/api-specification.html + +- WSDL Specification (SOAP) + https://docs.mobileid.ch/rest-api-guide/wsdl-specification.html + + +## OIDC Integration Guide + +- Introduction + https://docs.mobileid.ch/oidc-integration-guide/introduction.html + +- Getting Started + https://docs.mobileid.ch/oidc-integration-guide/getting-started.html + +- Best Practices + https://docs.mobileid.ch/oidc-integration-guide/best-practices.html + +- Passkey Authentication + https://docs.mobileid.ch/oidc-integration-guide/passkey-authentication.html + +- Public Cloud Integration + https://docs.mobileid.ch/oidc-integration-guide/cloud-integration-guide.html + +- OIDC Use Cases + https://docs.mobileid.ch/oidc-integration-guide/oidc-use-cases.html + +- App Message Formats + https://docs.mobileid.ch/oidc-integration-guide/message-formats.html + + +## RADIUS Gateway Guide + +- Introduction + https://docs.mobileid.ch/radius-interface-gateway-guide/introduction.html + +- RIG Deployment + https://docs.mobileid.ch/radius-interface-gateway-guide/deployment.html + +- Configuration + https://docs.mobileid.ch/radius-interface-gateway-guide/configuration.html + +- The RADIUS Protocol + https://docs.mobileid.ch/radius-interface-gateway-guide/radius-protocol.html + +- Annexes + https://docs.mobileid.ch/radius-interface-gateway-guide/annexes.html + + +## Release Notes + +- Release Notes Overview + https://docs.mobileid.ch/release-notes/ + +- Mobile ID Passkeys Launch (2026-03-30) + https://docs.mobileid.ch/release-notes/posts/2026-03-30-mobile-id-passkeys.html + + +## Additional resources + +- API Specification (OpenAPI / REST) + https://docs.mobileid.ch/rest-api-guide/api-specification.html + +--- + +## REST API Introduction + +Source: https://docs.mobileid.ch/rest-api-guide/introduction.html + +# Introduction + +The purpose of this document is to provide technical documentation and guidelines on how to use the Swisscom Mobile ID Authentication API. + +The Swisscom Mobile ID authentication solution protects access to your company data and applications with a comprehensive end-to-end solution for two-factor authentication (2FA). +Mobile ID can be used in multiple processes, from simple two-factor login to password-free authentication, online signatures, and geofencing. +It is suitable for various system landscapes and meets strict regulatory requirements. + +➡️ For more information, visit [https://mobileid.ch](https://mobileid.ch). + +## Terms and Abbreviations + +| Term | Description | +|------|--------------| +| **AP** | Application Provider | +| **AP_ID** | Application Provider Identifier | +| **DTBD** | *Data-To-Be-Displayed* — message displayed on the mobile phone (authentication context). | +| **DTBS** | *Data-To-Be-Signed* — equal to DTBD; the data that will be signed with the Mobile ID signing key. | +| **JSON** | JavaScript Object Notation — text-based open standard data interchange format. | +| **EC** | Swisscom [Enterprise Connect](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html) (replaces the former LAN-Interconnect). | +| **MID** | Mobile ID platform providing the mobile signature service. | +| **MNO** | Mobile Network Operator — also called wireless service provider or carrier. | +| **MSISDN** | Number uniquely identifying a mobile subscription in a GSM/UMTS network. | +| **MSSP** | Mobile Signature Service Provider — Swisscom Mobile ID backend application. | +| **OTA** | Over-The-Air management technology for SIM communication. | +| **RESTful** | Style of software architecture for distributed systems relying on HTTP. | +| **SOAP** | Simple Object Access Protocol — XML-based exchange protocol. | +| **WSDL** | Web Services Description Language — XML-based web-service contract description. | +| **X509** | Public-Key Infrastructure and digital certificates standard. | +| **XML** | Extensible Markup Language — structured, human- and machine-readable document format. | + +## MSS Signature Service + +Mobile ID is a cost-efficient, managed authentication service operated by Swisscom. +The customer-facing API follows the open standard [ETSI TS 102 204](https://www.etsi.org/deliver/etsi_ts/102200_102299/102204/) V1.1 (2003-08). + +Authentication in Mobile ID is based on a secure hardware token which can be either: + +- a Mobile ID-compliant SIM or eSIM, or +- a Mobile ID App running on a smartphone. + +Therefore, a user account could have either the (e)SIM method, the App method or even both methods activated at the same time. However, the Application Provider (AP) may select the preferred method and allow both methods or just either one. + +### **Mobile ID SIM - Method** + +An Application Provider (AP) can request SIM Toolkit (STK) based authentication, hereinafter referred to as "SIM method". To utilize the SIM method, the user must have a Mobile ID compliant SIM card or eSIM. Data exchange between the Mobile ID server and the STK application is done with SMS messages using data packets (PDUs), not visible to the end-user. The Mobile ID SIM Toolkit application runs on the SIM card environment and is compliant with all mobile devices. + + +mobileid-login-accept + + +#### **Key Advantages** + +- **Strong Two-Factor Authentication** + - **1st Factor:** Physical SIM/eSIM (Possession Factor) + - **2nd Factor:** Personal Mobile ID PIN (Knowledge Factor) + +- **High Level of Security** + - Tamper-proof secure hardware ([EAL5+](https://www.commoncriteriaportal.org/ccra/) and ITSEC E3 certified) + - Authentication via a separate encrypted channel + +- **Pre-installed** STK App on the SIM/eSIM profile + +- Supported by most **Swiss Mobile Network Operators** *(Swisscom, Sunrise, Salt)* + +### **Mobile ID App - Method** + +An Application Provider (AP) can request mobile app based authentication, hereinafter referred to as "App method". To utilize the App method, the user must have the Mobile ID App installed on a compliant Android or iOS-based smartphone. The app can be downloaded from the Google Play Store and Apple App Store. + +#### **Activation Options** + +The Mobile ID App activation can be done within the mobile app (in-app enrolment) or through the self-care portal (in the latter case, the app must scan a QR code displayed on www.mobileid.ch). + +1. **In-App Enrolment** + The user activates Mobile ID directly within the app. + +2. **Self-Care Portal Activation** + Activation via [https://www.mobileid.ch](https://www.mobileid.ch), + where the app scans a QR code displayed on the site. + +#### **Display Options** + +The App can display a plain UTF-8 string as a single text line. This is known as the +DTBD (DataToBeDisplayed) Classic View. + +app-display-utf8 + + + +The App also supports Transaction Approval Style, which enhances readability by displaying +a title (type-field) and one or more key-value rows. + +app-display-trans-approval + + +#### App Method Key Advantages + +- **Strong Two-Factor Authentication** + - **1st Factor:** Smartphone (Possession Factor) + - **2nd Factor:** Passcode (Knowledge Factor) or Biometry (Inherence Factor) + +- **High Level of Security** + - Authentication through dedicated mobile application (authentication app) + - Fast and secure (encrypted) communication + +- **Availability** + - The app is published and available in several countries of the European Union (EU) + +### **Authentication Flow** + +Before going into more technical details, let’s have a short look at the main scenario. + +**Strong Authentication**: +The end-user wants to access a corporate application protected by Mobile ID strong authentication. + +auth-flow-strong-flow + +#### Main Steps Performed by the End-User and the Mobile Signature Service + +1. The end-user uses any application relying on **Mobile ID** for authentication. + - The application sends a mobile signature request through the dedicated web interface (of the **AP**), including the personal **MSISDN** as an input parameter to log in. + +2. The **AP** receives the end-user request, forms the contents to be signed (in accordance with the **ETSI TS 102 204** standard), and forwards the request to the **MID** service. + +3. The **MID** platform receives the signature request and validates the **AP** in accordance with the service agreement. + +4. The **MID** platform ensures that the end-user signature request is allowed and forwards the signature request to the end-user’s mobile phone. + +5. The end-user receives a message on their mobile phone to sign the mobile signature request. + - The end-user confirms the authentication request either by providing the **Mobile ID PIN** (SIM method) or **Passcode/Biometry** (App method). + +After the **AP** has received a valid response, the end-user is granted access to the corporate application. + +--- + +## REST API Integration Steps + +Source: https://docs.mobileid.ch/rest-api-guide/app-provider-client-integration.html + +# Integration Steps + +This chapter describes how an Application Provider (AP) integrates its backend with the Swisscom Mobile ID signature service. It covers the necessary preconditions, endpoint configuration, and use of mutual TLS authentication. + +## Preconditions + +Before using the Swisscom Mobile ID web service, some initial provisioning steps are required. + +1. **The Mobile ID customer (your company) has an agreement with Swisscom:** + - **Connectivity** (Internet or [EC](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html)) between the **AP** and **Mobile ID** has been established. + - The customer has delivered the **X.509 client certificate** to Swisscom (see [Create X509 Client Certificates](/rest-api-guide/create-client-certs.md)). + +::: warning Firewall Whitelisting +The AP’s public source IP address (or range) must be whitelisted in the **Swisscom Firewall**. Contact Swisscom to request whitelisting. +::: + +2. **The Mobile ID customer receives from Swisscom:** + - An **AP_ID** (Application Provider Identifier) value. + - A **DataToBeDisplayed (DTBD) Prefix** value: + - The DTBD Prefix is an AP-specific keyword that must be included as a prefix in every Mobile ID request text message sent to a Mobile ID user (the message displayed on the user’s mobile phone). + - **Example:** `"Bank ACME: "` + +## Endpoint Address + +The Swisscom Mobile ID web service is accessible through EC ([Enterprise Connect](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html)) or the Internet. If not otherwise specified, use the following default access details. + + +| Environment | URL | +|-------------------|----------------------------------------| +| **Internet** | [https://mobileid.swisscom.com](https://mobileid.swisscom.com) | +| **Swisscom EC** | [https://195.65.233.218](https://195.65.233.218) | + +### Overview Access + +```mermaid +flowchart LR + subgraph CE[Customer Environment] + direction TB + AP[AP_ID
Application Provider] + end + + FW1{{Firewall}} + INTERNET((Internet)) + EC((EC)) + FW2{{Firewall}} + + subgraph ME[Mobile ID Backend] + direction TB + MSS[MSS Platform
Mobile Signature Service] + end + + AP --- FW1 + FW1 --- INTERNET + FW1 --- EC + INTERNET --- FW2 + EC --- FW2 + FW2 --- MSS + ``` + +::: info +For accessing the service endpoints the Mobile ID customer can choose between SOAP or RESTful endpoints. +::: + +### **SOAP Endpoint** + +A description of this interface is available as a WSDL file: mobileid.wsdl + +#### Endpoints + +| Endpoint URL | Description | Reference Section | +|---------------|--------------|-------------------| +| `/soap/services/MSS_SignaturePort` | **MSS Signature** | [Section MSS Signature](/rest-api-guide/mobile-id-api.html#mss-signature)| +| `/soap/services/MSS_StatusQueryPort` | **MSS Status Query** | [Section MSS Status Query](/rest-api-guide/mobile-id-api.html#mss-status-query)| +| `/soap/services/MSS_ReceiptPort` | **MSS Receipt** | [Section MSS Receipt](/rest-api-guide/mobile-id-api.html#mss-receipt) | +| `/soap/services/MSS_ProfilePort` | **MSS Profile Query** | [Section MSS Profile Query](/rest-api-guide/mobile-id-api.html#mss-profile-query) | + +### **REST Endpoint** +A description of this interface is available here: [API Specification](/rest-api-guide/api-specification) or you can download the corresponding YAML file: openapi-mobileid.yaml + +#### Endpoints + +| Endpoint URL | Description | Reference Section | +|---------------|--------------|-------------------| +| `/rest/service/sign` | **MSS Signature** | [Section MSS Signature](/rest-api-guide/mobile-id-api.html#mss-signature) | +| `/rest/service/status` | **MSS Status Query** |[Section MSS Status Query](/rest-api-guide/mobile-id-api.html#mss-status-query) | +| `/rest/service/receipt` | **MSS Receipt** | [Section MSS Receipt](/rest-api-guide/mobile-id-api.html#mss-receipt) | +| `/rest/service/profile` | **MSS Profile Query** | [Section MSS Profile Query](/rest-api-guide/mobile-id-api.html#mss-profile-query) | + + +## Mutual Authentication + +A certificate-based mutual authentication when accessing the Mobile ID web service is highly recommended. When using certificate-based mutual authentication, the following actions occur: + +![mutual-authentication](/img/mutual-authentication.png) + + +1. The client Application Provider (AP) requests access to a protected resource on the Mobile ID (MID) server. +2. The MID web server presents its server certificate to the client AP. +3. The client AP verifies the MID server certificate. +4. If verification is successful, the client AP sends its client certificate to the MID server. +5. The MID server verifies the AP client credentials. +6. If verification succeeds, the MID server grants access to the protected resource requested by the client AP. + + +### Important Guidelines for Certificate-Based Mutual Authentication + +- The client must send only its end-entity certificate. + - Authentication on the MID side does not consider validation of a full client certificate chain or any restrictions on the root CA. + - Authentication is denied if the client sends a bag with the full certificate chain. + +- The Enhanced Key Usage value of client certificates must include Client Authentication (`1.3.6.1.5.5.7.3.2`). + - See **[Create X509 Client Certificates](/rest-api-guide/create-client-certs.md)** for examples of creating self-signed certificates. + +::: danger +All requests to the Mobile ID service must originate only from servers that you control. +Never send requests directly from client-side code such as mobile apps or JavaScript, as this may compromise your credentials. +::: + +- To validate the chain of trust for the Mobile ID server certificate: + - Add the SwissSign Gold CA – G2 root certificate to your client TrustStore. + - The intermediate CAs are returned dynamically by the MID server and may change. + +::: info +Get the root certificate from https://www.swisssign.com/en/support/faq.html +::: + + + + + + +--- + +## REST API Mobile ID API + +Source: https://docs.mobileid.ch/rest-api-guide/mobile-id-api.html + +# Mobile ID API + +The Mobile ID service exposes a web API available via both SOAP and RESTful (JSON) interfaces. +Refer to [Application Provider Client Integration](/rest-api-guide/app-provider-client-integration) for a detailed description of these interfaces, including download links for the corresponding WSDL and YAML files that describe the service definitions. + +The OpenAPI specification for the RESTful API is also available here: +[API Specification](/rest-api-guide/api-specification) + + +## HTTP/1.1 Header + +### HTTP Request + +You can send signature requests using the HTTP/1.1 POST method over either the SOAP or RESTful interface. +The RESTful interface uses JavaScript Object Notation (JSON) as its media type. + +**Required HTTP Header Fields:** + +| Header Field | SOAP | RESTful / JSON | +|---------------|------|----------------| +| `Content-Type` | `text/xml;charset=UTF-8` | `application/json;charset=UTF-8` | +| `Accept` | – | `application/json` | + + +### HTTP Response + +- If the request succeeds, the Mobile ID server responds with: + `HTTP/1.1 200 OK` + +- If an error occurs while processing the request (for example: `USER_CANCEL`, `EXPIRED_TRANSACTION`, `UNKNOWN_CLIENT`, etc. — see **[Status and Fault Codes](/rest-api-guide/status-fault-codes)**), + the Mobile ID server responds with: + `HTTP/1.1 500 Internal Server Error` + + The response will include a message containing a Fault element that describes the processing error. + This behavior applies to both the SOAP and RESTful interfaces. + +## MSS Signature + +### Endpoint + +::: code-group +```bash [REST] +/rest/service/sign +``` +```bash [SOAP] +/soap/services/MSS_SignaturePort +``` +::: + + + + +### Signature Profiles + +For every authentication request, an AP can select the SIM or App authentication method by selecting a specific SignatureProfile-value in the MSS Signature request. + +This will give all the required flexibility for an AP to handle different use cases. For example, an AP may use an MSS Profile Query ([MSS Profile Query](/rest-api-guide/mobile-id-api#mss-profile-query)) request to silently check the user’s authentication method capabilities before an MSS Signature request ([MSS Signature Request](/rest-api-guide/mobile-id-api#mss-signature-request)) is sent. In other scenarios, the AP may want to force a specific authentication method. + +### Signature Profile Values + +| Signature Profile Value | Description | AP Authorization¹ | +|--------------------------|-------------|--------------------| +| `http://mid.swisscom.ch/MID/v1/AuthProfile1` | **Deprecated.** Should no longer be used.
By default, this signature profile is mapped to `http://mid.swisscom.ch/STK-LoA4`. | Any AP is authorized. | +| `http://mid.swisscom.ch/Any-LoA4` | Mobile ID backend will automatically choose **SIM** or **App** authentication based on the user’s configured methods:
– The **SIM** method is always preferred.
– The **App** method is only selected if it is the *only* active method for that user.

The response will indicate which authentication method was chosen. | By default, an AP is **not authorized** to use this profile.
Please contact **Swisscom** if you intend to use it. | +| `http://mid.swisscom.ch/STK-LoA4` | Forces **SIM authentication** method. | By default, an AP is **not authorized** to use this profile.
Please ask **Swisscom** if you intend to use it. | +| `http://mid.swisscom.ch/Device-LoA4` | Forces **App authentication** method. | By default, an AP is **not authorized** to use this profile.
Please ask **Swisscom** if you intend to use it. | +| `http://mid.swisscom.ch/Any-Geofencing-LoA4` | Mobile ID backend will choose **SIM** or **App** authentication based on both the user’s authentication and **geo-location** capabilities:
– **SIM** method is preferred but only if the SIM has geo-location capabilities (Swisscom SIM only).
– **App** method is selected if it is the only active method for that user, or if the user’s SIM lacks geo-location capabilities. | By default, an AP is **not authorized** to use this profile.
The AP must have **Geofencing Additional Service** permission.
Please ask **Swisscom** if you intend to use it. | + +::: warning Note +If an AP is not authorized to use a specific signature profile, the request is rejected with the fault response. +::: + +### User Scenario Examples (Signature Profile Handling) + +The following examples demonstrate how the Mobile ID backend responds to different signature profile values, depending on the user's active authentication methods (SIM, App, or both). + +The table below illustrates several example user scenarios and how the **MSSP** (Mobile ID backend) responds to a given **MSS Signature** request, depending on the user’s authentication capabilities and the selected **SignatureProfile** value. + +Please note that these examples are **illustrative**, not exhaustive. + + +#### AP configuration example + +- The AP is authorized to use all signature profiles. +- The AP has a signature profile mapping configured so that an incoming signature profile + `http://mid.swisscom.ch/MID/v1/AuthProfile1` + is mapped internally to + `http://mid.swisscom.ch/Any-LoA4`. +- These examples may not apply to every AP configuration; + some APs may not be authorized to use all signature profiles, + and others may not have a mapping configured. + +#### MSSP Response Logic per Scenario + +| MID User | SIM | App | Request’s Signature Profile | Response’s Signature Profile | +|-----------|-----|-----|-----------------------------|------------------------------| +| *(No active SIM / App)* | ✗ | ✗ | `http://mid.swisscom.ch/MID/v1/AuthProfile1` | n/a *(Fault 105 / UNKNOWN_CLIENT)* | +| | | | `http://mid.swisscom.ch/Any-LoA4` | n/a *(Fault 105 / UNKNOWN_CLIENT)* | +| | | | `http://mid.swisscom.ch/STK-LoA4` | n/a *(Fault 105 / UNKNOWN_CLIENT)* | +| | | | `http://mid.swisscom.ch/Device-LoA4` | n/a *(Fault 105 / UNKNOWN_CLIENT)* | +| **Active SIM only** | ✓ | ✗ | `http://mid.swisscom.ch/MID/v1/AuthProfile1` | `http://mid.swisscom.ch/STK-LoA4` | +| | | | `http://mid.swisscom.ch/Any-LoA4` | `http://mid.swisscom.ch/STK-LoA4` | +| | | | `http://mid.swisscom.ch/STK-LoA4` | `http://mid.swisscom.ch/STK-LoA4` | +| | | | `http://mid.swisscom.ch/Device-LoA4` | n/a *(Fault 109 / UNSUPPORTED_PROFILE)* | +| **Active App only** | ✗ | ✓ | `http://mid.swisscom.ch/MID/v1/AuthProfile1` | `http://mid.swisscom.ch/Device-LoA4` | +| | | | `http://mid.swisscom.ch/Any-LoA4` | `http://mid.swisscom.ch/Device-LoA4` | +| | | | `http://mid.swisscom.ch/STK-LoA4` | n/a *(Fault 109 / UNSUPPORTED_PROFILE)* | +| | | | `http://mid.swisscom.ch/Device-LoA4` | `http://mid.swisscom.ch/Device-LoA4` | +| **Active SIM and App** | ✓ | ✓ | `http://mid.swisscom.ch/MID/v1/AuthProfile1` | `http://mid.swisscom.ch/STK-LoA4` | +| | | | `http://mid.swisscom.ch/Any-LoA4` | `http://mid.swisscom.ch/STK-LoA4` | +| | | | `http://mid.swisscom.ch/STK-LoA4` | `http://mid.swisscom.ch/STK-LoA4` | +| | | | `http://mid.swisscom.ch/Device-LoA4` | `http://mid.swisscom.ch/Device-LoA4` | + + +::: info Note +An AP can use the **MSS Profile Query** request (see **[MSS Profile Query](/rest-api-guide/mobile-id-api#mss-profile-query)**) to determine a user’s capabilities. +For example, to check whether a particular user supports **SIM** and/or **App**-based authentication before sending the signature request. +::: + + +### Signature Messaging Mode + +The [ETSI TS 102 204](https://www.etsi.org/deliver/etsi_ts/102200_102299/102204/) standard has defined the MSS Signature and Swisscom supports both synchronous and asynchronous (client-server) modes. +The MSS_Signature method is used to submit the mobile signature request message (MSS_SignatureReq). The result is provided within the signature response message (MSS_SignatureResp). +The Mobile ID customer (AP) can decide to call either synchronous or asynchronous signature requests. There are different aspects to consider: + +- With the synchronous mode, the signature response is immediately processed by the AP after it has been made available by the Mobile ID Service, making the overall authentication transaction faster. If an Application Provider intends to invoke many signature transactions of different users in parallel, it may require more memory because each thread is waiting for its completion. + +- With the asynchronous client-server mode, the Application Provider needs to implement a polling mechanism (query the transaction status every x seconds until the signature has been made available by the Mobile ID Service). + + + +### Synchronous MSS Signature + +The following steps describe a typical synchronous (MessagingMode="synch") Mobile ID authentication transaction: + +![synchronous-mss-signature](/img/synchronous-mss-signature.png) + + +1. **End-User Action** + The end-user uses an application that initiates an authentication request. + +2. **Application Provider (AP) Request** + The AP receives the authentication request and sends an + `MSS_SignatureReq` message with parameter `MessagingMode="synch"` to the MSSP (Mobile ID backend). + +3. **AP Credential Validation** + The **Mobile ID backend (MSSP)** validates the **AP’s credentials** and verifies its authorization. + +4. **Signature Request to User Device** + The **Mobile ID backend** sends a signature request to the mobile device — either to the **SIM (STK applet)** or to the **Mobile ID App**, depending on the user’s configured method. + +5. **User Authentication & Digital Signature** + The Mobile ID application on the mobile device prompts the user to enter their Mobile ID secret (PIN, passcode, or biometric factor). + - The user confirms with the correct secret. + - The mobile application digitally signs the authentication payload. + - The resulting digital signature is returned to the Mobile ID backend (MSSP). + +6. **Signature Response Received** + The MSSP receives the signature response and processes it. + +7. **Response to Application Provider** + The **Mobile ID backend** returns a **complete response** to the **AP**, containing: + - The **digital signature**, and + - The **certificate** that includes the end-user’s public key. + +8. **Access Decision by the AP** + Based on the Mobile ID response, the AP may grant or deny access to the end-user, depending on the authentication outcome. + + +#### Synchronous MSS Signature Request + +::: code-group +```json [REST/json] + +{ + "MSS_SignatureReq": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T12:00:00.000+01:00" + }, + "AdditionalServices": [ + { + "Description": "http://mss.ficom.fi/TS102204/v1.0.0#userLang", + "UserLang": { + "Value": "LANGUAGE" + } + } + ], + "DataToBeSigned": { + "Data": "TEXT_TO_BE_SIGNED", + "Encoding": "UTF-8", + "MimeType": "text/plain" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "1", + "MessagingMode": "synch", + "MinorVersion": "2", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "SignatureProfile": "SIGNATURE_PROFILE", + "TimeOut": "80" + } +} + +``` +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + TEXT_TO_BE_SIGNED + + SIGNATURE_PROFILE + + + + + http://mss.ficom.fi/TS102204/v1.0.0#userLang + + LANGUAGE + + + + + + + +``` +::: + + +::: info +`MinorVersion` value must be set to “2” in case of a REST/JSON request message. +::: + + +#### Synchronous MSS Signature Response + + +::: code-group + +```json [REST/json] + +{ + "MSS_SignatureResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2015-01-01T11:00:00.100Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h44okl", + "MSS_Signature": { + "Base64Signature": "MIIIdwYJKoZIhvc..." + }, + "MajorVersion": "1", + "MinorVersion": "1", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "SignatureProfile": "SIGNATURE_PROFILE", + "Status": { + "StatusCode": { + "Value": "500" + }, + "StatusMessage": "SIGNATURE" + } + } +} + + +``` + +```xml [SOAP/xml] + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + MIIIdwYJKoZIhvc... + + + SIGNATURE_PROFILE + + + + SIGNATURE + + + + + + +``` + +::: + +The `Base64Signature` content is a base 64 encoded [CMS](https://datatracker.ietf.org/doc/html/rfc5652) (which is an extension of PKCS#7) signature object. It contains the DTBD message that has been signed by the SIM- or mobile application on the mobile device. In addition, it includes the mobile user certificate and all related intermediate certificates. Therefore, the AP will always be able to fully validate the signature response. +Note that the response contains the signature profile value to indicate what authentication method was chosen, which is helpful in case the request signature profile was `http://mid.swisscom.ch/Any-LoA4`. + + +#### Fault Response +This is an example fault response in case of an illegal MSISDN value. Each fault response contains a (sub-)code value, reason text and detail text. Refer to section 6 for a list of status and error codes. + +::: code-group + +```json [REST/json] + +{ + "Fault": { + "Code": { + "SubCode": { + "Value": "_101", + "ValueNs": "http://uri.etsi.org/TS102204/v1.1.2#" + }, + "Value": "Sender", + "ValueNs": "http://www.w3.org/2003/05/soap-envelope" + }, + "Detail": "Illegal msisdn", + "Reason": "WRONG_PARAM" + } +} + + +``` + +```xml [SOAP/xml] + + + + + + soapenv:Sender + + mss:_101 + + + + WRONG_PARAM + + + Illegal msisdn + + + + + +``` + +::: + + +### Asynchronous MSS Signature + +In the asynchronous mode, the AP initiates the signature request by calling MSS_Signature method and an acknowledgment response is sent back immediately by the MID to AP. The AP client then starts poll-ing using MSS_StatusQuery service to receive the response as depicted below. + +![async-mss-signature](/img/async-mss-signature.png) + + +1. End-User uses an application that sends an authentication request. +2. AP receives the request and sends an asynchronous MSS_SignatureReq request message to MSSP. +3. MID backend validates the AP credentials. +4. MID responds to AP with MSS_SignatureResp7 message (acknowledgment). +5. MID sends a signature request to the application on the mobile device (either SIM or App). +6. The mobile application (STK applet or Mobile App) prompts the End-User to enter the Mobile ID secret (PIN, passcode, biometry). End-User confirms with the correct secret and the application digitally signs the request and sends the signature back to the Mobile ID backend (MSSP). + +::: info +Meanwhile the AP sends MSS_StatusReq requests to MID. The MID replies with MSS_StatusResp (status code “504 OUTSTANDING_TRANSACTION”, which means that the AP will need to call again the status method). +::: + +7. Mobile ID backend (MSSP) receives the signature response. +8. AP sends next MSS_StatusReq request message to MID. +9. MID sends a complete response (signature + certificate containing the end-user's public key) to the AP as MSS_StatusResp Response. +10. Depending on the response of MID, the AP may grant or deny access to the End-User. + + +#### Asynchronous MSS Signature Request +In pink the differences compared to the sync mode. This value isn’t the same for SOAP and REST. + +::: code-group + +```json [REST/json] + +{ + "MSS_SignatureReq": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T12:00:00.000+01:00" + }, + "AdditionalServices": [ + { + "Description": "http://mss.ficom.fi/TS102204/v1.0.0#userLang", + "UserLang": { + "Value": "LANGUAGE" + } + } + ], + "DataToBeSigned": { + "Data": "TEXT_TO_BE_SIGNED", + "Encoding": "UTF-8", + "MimeType": "text/plain" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "1", + "MessagingMode": "asynch", + "MinorVersion": "2", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "SignatureProfile": "SIGNATURE_PROFILE", + "TimeOut": "80" + } +} + + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + TEXT_TO_BE_SIGNED + + SIGNATURE_PROFILE + + + + + http://mss.ficom.fi/TS102204/v1.0.0#userLang + + LANGUAGE + + + + + + + + + +``` + +::: + +::: info +`MinorVersion` value must be set to “2” in case of a REST/JSON request message. +::: + +#### Asynchronous MSS Signature Response + +::: code-group + +```json [REST/json] +{ + "MSS_SignatureResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2015-01-01T11:00:00.100Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h4iof", + "MajorVersion": "1", + "MinorVersion": "1", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "SignatureProfile": "SIGNATURE_PROFILE", + "Status": { + "StatusCode": { + "Value": "100" + }, + "StatusMessage": "REQUEST_OK" + } + } +} + + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + SIGNATURE_PROFILE + + + + REQUEST_OK + + + + + + +``` + +::: + +::: info +The response contains the signature profile value to indicate what authentication method was chosen, which is helpful in case the request signature profile was `http://mid.swisscom.ch/Any-LoA4`. +::: + +### Additional Services (AS) +The **MSS Signature** supports additional services that may be requested in the request message. Some of them are mandatory and some are optional. + +#### User Language + +The `UserLang` is a mandatory service for all Signature Requests. +One of the supported languages (EN, DE, FR, IT) must be defined. Please refer to section Synchronous MSS Signature Request or Asynchronous MSS Signature for an example. It should correspond to the language of the DataToBeDisplayed (DTBT) text message. +Example usage (code snippet from the MSS Signature Request): + +::: code-group + +```json [REST/json] + +"AdditionalServices": [ + { + "Description": "http://mss.ficom.fi/TS102204/v1.0.0#userLang" + } +] + + +``` + +```xml [SOAP/xml] + + + + + http://mss.ficom.fi/TS102204/v1.0.0#userLang + + + + + + +``` + +::: + +#### Geofencing + +Geofencing is an optional service that enables Application Providers to define geographical boundaries. They can decide who can access what within that barrier, based on the user’s location data at the moment of the Mobile ID authentication. This technology can help Application Providers to lock an application use to a specific geographic location and block any Mobile ID authentication requests outside of the fencing area. + +With the geofencing service, any authorized Application Provider (AP) may request the user’s location data in an MSS Signature request. + +Geofencing can be requested with the MSS Signature's additional service URI set to `http://mid.swisscom.ch/as#geofencing`. + +##### Geofencing Policy Enforcement + +There are three different ways to enforce a Geofencing policy. + +1. The AP requests the Geofencing additional service by adding the URI http://mid.swisscom.ch/as#geofencing to the MSS Signature request: + +```json +"AdditionalServices": [ + { + "Description": "http://mid.swisscom.ch/as#geofencing" + } +] + +``` +A successful MSS Signature response will contain the geolocation data: + +```json +"MSS_SignatureResp": { + … + "ServiceResponses": [ { + "Description": "http://mid.swisscom.ch/as#geofencing", + "Geofencing": { + "Accuracy": "16", + "Country": "CH", + "DeviceConfidence="0.9", + "LocationConfidence="0.85", + "Timestamp": "2021-01-01T11:00:00.000+01:00" + } + } ] + … +} +``` +The AP parses the Service Response and implements the authorization accordingly. + +2. In addition to the 1st example, the AP adds a Geofencing Policy to the MSS Signature request: + +```json +"AdditionalServices":[ + { + "Description":"http://mid.swisscom.ch/as#geofencing", + "GeoFencingRequest":{ + "countrywhitelist":[ + "CH", + "DE", + "AT" + ], + "countryblacklist":[ + ], + "mindeviceconfidence":"0.7", + "minlocationconfidence":"0.7", + "maxtimestampminutes":"600", + "maxaccuracymeters":"1000" + } + } +] +``` +The policy may contain a country-based whitelist or blacklist and minimum threshold values for the confidence scores, timestamp and accuracy. The Mobile ID server will enforce the policy. + +3. A custom Geofencing Policy is set on the Mobile ID server. Here's an example, how a Geofencing Policy can be set on the Mobile ID server (of course the values can be adjusted according to the AP's need): + +```json +{ + "enabled":"true", + "verbose":"false", + "countrywhitelist":[ + "CH", + "DE", + "AT" + ], + "countryblacklist":[ + ], + "mindeviceconfidence":"0.7", + "minlocationconfidence":"0.7", + "maxtimestampminutes":"600", + "maxaccuracymeters":"1000" +} + +``` +The policy may contain a country-based whitelist or blacklist and minimum threshold values for the confidence scores, timestamp and accuracy. +In this case, the AP can request the Geofencing service as shown in the 1st example. The Mobile ID server will enforce the custom Geofencing Policy that has been set for the AP. + +##### Geofencing Service Data and Confidence Scores + +| Key | Value Example | Format | Description | +|-----|---------------|--------|-------------| +| Country | CH | ISO 3166-1 alpha-2 | A two-letter country code of the current SIM or Device location. Based on the currently registered mobile cell (SIM) or reverse geocoding of the device's GPS coordinates (App). | +| Accuracy | 16 | Integer | Accuracy of the Device GPS, in meters. For SIM authentications, accuracy is always 0. For App authentications, it is the sum of the GPS accuracy and distance to the nearest geocoding data point. | +| DeviceConfidence | 0.99 | Float (0–1.00) | Trust level in the user device and OS version. Value 1.0 represents the highest possible trust. Based on internal checks including root/jailbreak detection. | +| LocationConfidence | 0.85 | Float (0–1.00) | Trust level in the user location data, which includes device confidence in its calculation. Value 1.0 represents the highest possible trust. Score decreases by 0.01 every hour if location data is not updated. | +| Timestamp | 2021-01-01T11:00:00.000+01:00 | yyyy-MM-dd'T'HH:mm:ss.SSS'Z' | The timestamp of the location information. | + +::: tip Recommendations per Service Data Key +- **Country**: Allow or block access based on the country code returned in this response. +- **Accuracy**: For Mobile ID App authentications, the accuracy depends on various factors. When the user is inside buildings or underground, the GPS is sometimes inaccurate. On latest iOS and Android, the user may also disable location precision, which will cause a high value for accuracy. +- **DeviceConfidence**: A score below 0.5 is an indication that the user's device may be rooted or jailbroken. +- **LocationConfidence**: Typically, a location confidence of 0.7 or higher can be considered as a sufficient trust level. Please also refer to the confidence score interpretation below. +- **Timestamp**: Mobile Session (registered cell) information or GPS location data may not be up-to-date and may require action from the mobile user. Turning on and off the Device FlightMode feature will help to have up-to-date location data. +::: +::: tip Recommendations for Confidence Score Checks +Usually it is sufficient if a client implements a minimum threshold check for the Location Confidence Score since the Location Confidence Score includes the Device Confidence Score in its calculation. Here’s a rationale regarding the Location Confidence Score: +::: + +![confidence-score](/img/confidence-score.png) + +- A score of `1.0` as minimum target threshold is recommended for extremely critical services only! It requires the user to have a Swisscom SIM and up-to-date SIM location data (not older than 1 hour). Turning on and off the Device FlightMode feature will help to have up-to-date location data. +- A score of `0.8` as minimum target threshold can be considered as a very high trust score and is a recommended target threshold for most critical services. +- A score of `0.7` as minimum target threshold is still a better confidence score than IP based location solutions and therefore a recommended target threshold for most standard services. + +::: warning Low Location Confidence Score +In case a user has a too low location confidence score, the following points should be checked by the user: + +**Timestamp value indicates that location data is older than 1 hour:** +- Turn on and off the FlightMode, which usually helps to have up-to-date location data. + +**Location- and Device Confidence Score are very low:** +- User must not use a rooted or jailbroken device. + +**Location Confidence Score too low:** +- User must have Developer Mode disabled. +- User must uninstall any 3rd party app that use Mock Location capabilities. +::: + +::: info Geofencing Service Limitations +- Geofencing information is given without any guarantee and with the exclusion of any legal liability. +- At the time of writing only MobileID App or Swisscom Mobile ID SIM cards support location data. +- For the MobileID App, the user must have the geofencing toggle enabled and location services permitted. Both Android and iOS App version 1.2.0 or higher support geofencing. +::: + + + +##### MSS Signature Request incl. Geofencing + +::: code-group + +```json [REST/json] + +{ + "MSS_SignatureReq": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T12:00:00.000+01:00" + }, + "AdditionalServices": [ + { + "Description": "http://mid.swisscom.ch/as#geofencing" + }, + { + "Description": "http://mss.ficom.fi/TS102204/v1.0.0#userLang", + "UserLang": { + "Value": "LANGUAGE" + } + } + ], + "DataToBeSigned": { + "Data": "TEXT_TO_BE_SIGNED", + "Encoding": "UTF-8", + "MimeType": "text/plain" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "1", + "MessagingMode": "synch", + "MinorVersion": "1", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "SignatureProfile": "http://mid.swisscom.ch/MID/v1/AuthProfile1", + "TimeOut": "80" + } +} + + +``` + +```xml [SOAP/xml] + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + TEXT_TO_BE_SIGNED + + http://mid.swisscom.ch/MID/v1/AuthProfile1 + + + + + http://mss.ficom.fi/TS102204/v1.0.0#userLang + + LANGUAGE + + + + http://mid.swisscom.ch/as#geofencing + + + + + + +``` +::: + +##### MSS Signature Response incl. Geofencing Location Data + +::: code-group + +```json [REST/json] + +{ + "MSS_SignatureResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2021-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2021-01-01T11:00:00.000Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h44okl", + "MSS_Signature": { + "Base64Signature": "MIIIdwYJKoZIhvc..." + }, + "MajorVersion": "1", + "MinorVersion": "1", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "ServiceResponses": [ { + "Description": "http://mid.swisscom.ch/as#geofencing", + "Geofencing": { + "Accuracy": "16", + "Country": "CH", + "DeviceConfidence="1.0", + "LocationConfidence="1.0", + "Timestamp": "2021-01-01T11:00:00.000+01:00" + } + } ], + "SignatureProfile": "SIGNATURE_PROFILE", + "Status": { + "StatusCode": { + "Value": "500" + }, + "StatusMessage": "SIGNATURE" + } + } +} + + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + MIIIdwYJKoZIhvc... + + + SIGNATURE_PROFILE + + + + SIGNATURE + + + + + http://mid.swisscom.ch/as#geofencing + + + + + + + + + + + +``` + +::: + + +##### MSS Signature Response incl. Geofencing Fault Code + +::: code-group + +```json [REST/json] +{ + "MSS_SignatureResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2021-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2021-01-01T11:00:00.000Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h44okl", + "MSS_Signature": { + "Base64Signature": "MIIIdwYJKoZIhvc..." + }, + "MajorVersion": "1", + "MinorVersion": "1", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "ServiceResponses": [ { + "Description": "http://mid.swisscom.ch/as#geofencing", + "Geofencing": { + "ErrorCode": "100", + "ErrorMessage": "Geofencing feature disabled" + } + } ], + "SignatureProfile": "SIGNATURE_PROFILE", + "Status": { + "StatusCode": { + "Value": "500" + }, + "StatusMessage": "SIGNATURE" + } + } +} + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + MIIIdwYJKoZIhvc... + + + SIGNATURE_PROFILE + + + + SIGNATURE + + + + + http://mid.swisscom.ch/as#geofencing + + + + + + + + + + + +``` + +::: + + +##### Geofencing Error Codes + +::: details Click to expand the full list of Geofencing error codes +The table below contains all error codes that the geofencing additional service may return. Note that the exact error message may vary for a given error code. + +| Code | Message | +|------|---------| +| 100 | The geofencing feature option in the "More" menu is currently disabled. | +| 101 | The app failed to retrieve the user's location possibly due to insufficient resources (network, GPS, etc.) or a timeout. | +| 102 | The user has not yet responded to the dialog that grants the app permission to access location services. | +| 103 | The user has explicitly denied the app permission to access location services. | +| 104 | This is on iOS only. The user cannot enable location services possibly due to active restrictions such as parental controls, corporate policy etc. being in place. | +| 105 | The user has turned off location services device-wide (for all apps) from the system settings. | +| 106 | Location services are unavailable because the device is in Airplane mode. | +| 120 | Location failed to the app for an unspecified reason. | +| 121 | MSSP internal error (misconfiguration etc.). | +| 122 | AP is not authorized to use Geofencing additional service. | +| 123 | User has a non-Swisscom SIM card. | +| 200 | No location returned from mobile app. | +| 201 | App outdated, geofencing not supported. | +::: + + + +#### App to App - Mobile Only Authentication + +We strongly recommend making use of this service if you intend to invoke the Mobile ID authentication from your own App. The Mobile ID App2App service allows an Application Provider to automatically switch from their App to the Mobile ID App (and the Mobile ID App to automatically switch back to the originating App) as shown in step 10 and 18 in the sequence below. This will greatly improve the usability for the App user. + +![mobile-only-auth](/img/mobile-only-auth.png) + +**Setup Phase** *(Steps 1–5)* + +1. While being in the Application Provider App, the user performs an action that requires authentication +2. The Application Provider App informs the Application Provider backend +3. Optional: The Application Provider backend can request the Mobile ID capabilities of the user +4. Optional: Mobile ID backend checks the user’s capabilities and provides the response +5. Optional: Application Provider gets all user details to know if the user has an active Mobile ID App + +**Authentication Phase** *(Steps 6–16)* + +6. The Application Provider sends an asynchronous signature request that includes the App2App service request. The URI value of the Application Provider App is provided as RedirectURI parameter. +7. Mobile ID API responds immediately with a Signature Response, which contains the AuthURI parameter. This is the URI value of the Mobile ID App. +8. The Application Provider App can either immediately trigger the Mobile ID App (step 8a) or display a button, which will trigger the Mobile ID App (step 8b) +9. The AuthURI is triggered by the Application Provider App +10. The Mobile ID App is automatically opened on the user’s smartphone +11. The Mobile ID backend invokes the authentication request on the Mobile ID App +12. The Mobile ID authentication message is shown on the Mobile ID App +13. The user confirms the authentication request with their 2nd factor (Passcode or Biometry) +14. The Mobile ID App signs the message with the private key stored on the device +15. The Mobile ID App sends the signed data (signature) to the Mobile ID backend +16. The Mobile ID backend completes the transaction + +**Completion Phase** *(Steps 17–22)* + +17. The RedirectURI is triggered by the Mobile ID App +18. The Application Provider App is automatically opened on the user’s smartphone +19. The Application Provider polls the Mobile ID transaction status by sending a MSS Status Request +20. The Status Response returns the final Mobile ID Signature (if outstanding, step 19 is repeated) +21. Optional: The Application Provider validates the CMS Signature to ensure that the Signature is valid +22. The Application Provider forwards the successful Mobile ID authentication result to their App + +Example usage (code snippet from the MSS Signature Request): + +::: code-group + +```json [REST/json] + +"AdditionalServices": [ + { + "Description": "http://mid.swisscom.ch/as#app2app", + "App2App": { + "RedirectUri": "myapp://example" + } + } +] +``` + +```xml [SOAP/xml] + + + + + http://mid.swisscom.ch/as#app2app + + + myapp://example + + + + + + +``` + +::: + + +::: tip Best Practice Guidelines +- It is highly recommended for an Application Provider to implement the App2App service as it will greatly improve the usability for any user that uses the Mobile ID App as authentication method. +- Both Android and iOS are supported for the automatic App2App switch. +- This service can only be used with the asynchronous MSS Signature. In case a synchronous MSS Signature with App2App service is attempted, Mobile ID API will respond with a fault (WRONG_PARAM). +- In case this service is requested, there will be no Mobile ID push notification triggered. That’s because a push notification is not required if the Mobile ID App is automatically opened. +- Please refer also to the official documentation from Apple and Android about how to implement custom URL schemes in your app. +::: + + +##### MSS Signature Request incl. App2App service + +::: code-group + +```json [REST/json] + +{ + "MSS_SignatureReq": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T12:00:00.000+01:00" + }, + "AdditionalServices": [ + { + "Description": "http://mss.ficom.fi/TS102204/v1.0.0#userLang", + "UserLang": { + "Value": "DE" + } + }, + { + "Description": "http://mid.swisscom.ch/as#app2app", + "App2App": { + "RedirectUri": "myapp://example" + } + } + ], + "DataToBeSigned": { + "Data": "TEXT_TO_BE_SIGNED", + "Encoding": "UTF-8", + "MimeType": "text/plain" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "1", + "MessagingMode": "asynch", + "MinorVersion": "2", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "SignatureProfile": "http://mid.swisscom.ch/Device-LoA4", + "TimeOut": "80" + } +} + +``` + +```xml [SOAP/xml] + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + TEXT_TO_BE_SIGNED + + http://mid.swisscom.ch/Device-LoA4 + + + + + http://mss.ficom.fi/TS102204/v1.0.0#userLang + + LANGUAGE + + + + http://mid.swisscom.ch/as#app2app + + + myapp://example + + + + + + +``` + +::: + + +##### MSS Signature Response incl. App2App service response + +::: code-group + +```json [REST/json] + +{ + "MSS_SignatureResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2015-01-01T11:00:00.100Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h4iof", + "MajorVersion": "1", + "MinorVersion": "2", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "ServiceResponses": [ + { + "App2App": { + "AuthUri": "mobileid://auth?mobile_auth_redirect_uri=myapp%3A%2F%2Fapp.open%23access_token%3DABCD& + session_token=32ffc297-0N5F0yEk2ArMZjFhBWPb4Uifwbk1f3p9ciAURd_QhUQ9e&user_id=32ffc297- + ac33-4be2-b3f4-42588502ea0f" + }, + "Description": "http://mid.swisscom.ch/as#app2app" + } + ], + "SignatureProfile": "http://mid.swisscom.ch/Device-LoA4", + "Status": { + "StatusCode": { + "Value": "100" + }, + "StatusMessage": "REQUEST_OK" + } + } +} + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + http://mid.swisscom.ch/Device-LoA4 + + + + REQUEST_OK + + + + + http://mid.swisscom.ch/as#app2app + + + + mobileid://auth?mobile_auth_redirect_uri=myapp%3A%2F%2Fapp.open%23access_ + token%3DABCD&session_token=32ffc297-0YLukZtgoRVz_wbJJfLnViViEhzk9aXM8 + dkHoOnhqf158&user_id=32ffc297-ac33-4be2-b3f4-42588502ea0f + + + + + + + + + + +``` + +::: + + +### Message Formats on the Mobile ID App + +Mobile ID App screens can present the Data-To-Be-Displayed (DTBD) in two formats. +Use **Classic DTBD** for short confirmations and when you must support SIM users. Keep messages concise and always include the “DTBD Prefix” (refer to chapter 2.1). +Use **Transaction Approval** when readability matters (e.g., PSD2 payments, contract consent, step up login verification). Force the App method with Device LoA4, keep within byte limits, and generate the escaped JSON programmatically. + +1. Classic DTBD (single text line) uses plain UTF-8 string that is also signed (DTBS). + +Supported by SIM and App methods. + +Length limited and no formatting options. + +![app-display-utf8](/img/app-display-utf8.png) + + +2. Transaction Approval (key/value pairs) is a structured App-only format that renders a title (type) and one or more key and value rows for improved readability. + +Approve/Cancel becomes active only after the user scrolls to the end if content exceeds one screen. + +![app-display-trans-approval](/img/app-display-trans-approval.png) + + +#### Classic DTBD (single-line text) + +A single UTF-8 string shown on the device. It is the format used throughout the guide’s MSS Signature examples. The classic DTBD must include the AP-specific DTBD prefix (e.g., `Bank ACME:`) and is support-ed by both SIM and App methods. +Keep the DTBD short. Maximum 239 characters; if any character falls outside the GSM 03.38 set, effec-tive maximum is 119 characters. + +Use `MimeType = "text/plain"` and place the “DTBD Prefix”. + +**Example Payload / Classic DTBD:** + +::: code-group + +```json [REST/json] +"DataToBeSigned": { + "MimeType": "text/plain", + "Encoding": "UTF-8", + "Data": "Bank ACME: Please confirm that you authorize Acme AG to change your registered + address from Bahnhofstrasse 1, 8001 Zürich to Sihlquai 55, 8005 Zürich + effective 01 June 2025. Reply APPROVE to consent or CANCEL. Changes + apply to all company services." +}, +``` + +```xml [SOAP/xml] + + Bank ACME: Please confirm that you authorize Acme AG to change your registered + address from Bahnhofstrasse 1, 8001 Zürich to Sihlquai 55, 8005 Zürich + effective 01 June 2025. Reply APPROVE to consent or CANCEL. Changes + apply to all company services. + +``` + +::: + +#### Transaction Approval (key/value pairs) + +A structured DTBD that the Mobile ID App renders as a title and rows of key/value pairs. If content overflows, the user must scroll to the bottom; only then are Approve/Cancel enabled. + +SIM does not support this format. Always select an App profile (e.g., `Device-LoA4`). + +**Rules:** +- MimeType: `application/vnd.mobileid.txn-approval` +- Payload structure (DataToBeSigned.Data): A single-line JSON string (escaped) with: + + +```json +{ + "type": "Title to display", + "dtbd": [ + { "key": "Label 1", "value": "Value 1" }, + { "key": "Label 2", "value": "Value 2" } + ] +} + +``` + +* DTBD Prefix: Your prefix must appear in the `value` of the first key/value pair. +* Size limits: + * type ≤ 100 bytes + * ≤ 20 pairs + * each key ≤ 100 bytes + * each value ≤ 2 000 bytes + * sum of all keys+values ≤ 2 000 bytes. +* Signature profile: Force App method with `http://mid.swisscom.ch/Device-LoA4` + + +Signed content (what the App actually signs): The App normalizes and signs only the array content, not the type. Example transformation: +Input: `{"type":"Login","dtbd":[{"key":"Company","value":"Test"}]}` + +Signed: `{"for-mat_version":1,"content_string":"[{\"key\":\"Company\",\"value\":\"Test\"}]"}` + +::: warning +`type` is not signed. If the title/category matters for your process (e.g., “PSD2 Payment”), add a dedicated dtbd row for it (e.g., {"key":"Category","value":"PSD2 Payment"}). +::: + +**Example Payload / Transaction Approval:** + +::: code-group + +```json [REST/json] + +"DataToBeSigned": { + "MimeType": "application/vnd.mobileid.txn-approval", + "Encoding": "UTF-8", + "Data": "{\"type\":\"Address Change Confirmation\",\"dtbd\":[{\"key\":\"Company\",\"value\":\"Acme AG\"},{\"key\":\"Full Name\",\"value\":\"Philipp Haupt\"},{\"key\":\"Old Address\",\"value\":\"Bahnhofstrasse 1, 8001 Zürich\"},{\"key\":\"New Address\",\"value\":\"Sihlquai 55, 8005 Zürich\"},{\"key\":\"Effective Date\",\"value\":\"01 June 2025\"},{\"key\":\"Consent Instruction\",\"value\":\"Reply APPROVE to consent or CANCEL\"}]}" +} + +``` + +```xml [SOAP/xml] + + {\"type\":\"Address Change Confirmation\",\"dtbd\":[ + {\"key\":\"Company\",\"value\":\"Acme AG\"}, + {\"key\":\"Full Name\",\"value\":\"Philipp Haupt\"}, + {\"key\":\"Old Address\",\"value\":\"Bahnhofstrasse 1, 8001 Zürich\"}, + {\"key\":\"New Address\",\"value\":\"Sihlquai 55, 8005 Zürich\"}, + {\"key\":\"Effective Date\",\"value\":\"01 June 2025\"}, + {\"key\":\"Consent Instruction\",\"value\":\"Reply APPROVE to consent or CANCEL\"} + ]} + +``` + +::: + +::: tip +Generate the escaped string programmatically (e.g. `JSON.stringify` / `json.dumps` / `jq -c`) and never hand-craft escapes. +If MimeType is TXN-Approval but the payload isn’t valid, the server flags `INVALID_TXNAPPROVAL_PAYLOAD` and can return a Fault. +::: + +**Side by side comparison:** + + +| Aspect | Classic DTBD (single line) | Transaction Approval (key/value) | +|--------|----------------------------|----------------------------------| +| Supported channel | SIM & App | App only | +| DataToBeSigned.MimeType | `text/plain` | `application/vnd.mobileid.txn-approval` | +| Data content | Plain UTF-8 string | Escaped single line JSON with `type` and `dtbd` | +| DTBD prefix requirement | Prefix must be present in the text (e.g., `Acme AG: …`). | Prefix must be present in `value` of the 1st pair. | +| Size limits | 239 chars (119 if non-GSM chars). | `type` ≤ 100 B; ≤ 20 pairs; each `key` ≤ 100 B; each value ≤ 2,000 B; sum of all keys+values ≤ 2,000 B. | +| UI behavior | Single text block. | Title + rows; must scroll to bottom to enable Approve/Cancel. | +| Signed bytes | The visible string (DTBD/DTBS). | Normalized JSON containing the `dtbd` array only (`format_version`, `content_string`); `type` not signed. | + + +## MSS Status Query +In case of an asynchronous MSS Signature, the AP needs to poll the status of an ongoing signature transaction by sending MSS Status Query requests. + +### Endpoint + +::: code-group +```bash [REST] +/rest/service/status +``` +```bash [SOAP] +/soap/services/MSS_StatusQueryPort +``` +::: + +### MSS Status Query Request +With the MSS Status Query an AP can poll the final MSS Signature result. At this point in time, AP has received the MSS_SignatureResp with the `MSSP_TransID="h4iof"`. The AP must take the received `MSSP_TransID="h4iof"` and use it in the MSS_StatusReq. + +::: code-group + +```json [REST/json] +{ + "MSS_StatusReq": { + "MajorVersion": "1", + "MinorVersion": "1", + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "Instant":"2015-01-01T12:00:00.000+01:00", + "AP_TransID":"REF0101120000" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h4iof" + } +} + +``` + +```xml [SOAP/xml] + + + + + + + + http://mid.swisscom.ch/ + + + + + + +``` + +### MSS Status Query Response + +Here is an example Status Response with the final MSS Signature result (status 500/SIGNATURE). + +::: code-group + +```json [REST/json] +{ + "MSS_StatusResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2015-01-01T11:00:00.100Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSS_Signature": { + "Base64Signature": "MIIIdwYJKoZIhvc..." + }, + "MajorVersion": "1", + "MinorVersion": "1", + "MobileUser": MOBILE_NUMBER, + "Status": { + "StatusCode": { + "Value": "500" + }, + "StatusMessage": "SIGNATURE" + } + } +} + +``` +```xml [SOAP/xml] + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + MIIIdwYJKoZIhvc... + + + + SIGNATURE + + + + + + +``` +::: + +::: info +The Status Query response does not contain the signature profile value, as this value was already returned with the asynchronous MSS Signature response. +::: + +A typical status code for this method is `504`, which means that the transaction is not yet completed, and the AP must call MSS_StatusReq again (polling). Example for an MSS_StatusResp with a `504` Status Code: + +::: code-group + +```json [REST/json] + + "Status": { + "StatusCode": {"Value": "504"}, + "StatusMessage": "OUTSTANDING_TRANSACTION" + } + +``` + +```xml [SOAP/xml] + + + + OUTSTANDING_TRANSACTION + + +``` + +::: + + +## MSS Receipt + +An AP may use this operation after a successful mobile signature request to provide the End-User with a "receipt" that informs him of the mobile signature transaction status. +However, only one receipt per successful signature transaction can be sent. +Only synchronous Signature Receipts are supported. There is no support for asynchronous Signature Receipts. + +### Endpoint + +::: code-group +```bash [REST] +/rest/service/receipt +``` +```bash [SOAP] +/soap/services/MSS_ReceiptPort +``` +::: + + +### Synchronous MSS Receipt +In the synchronous mode, the AP initiates the receipt request by calling MSS_ReceiptReq, which is then blocked until the signature has been acknowledged, cancelled or the signing times out occurs. The picture depicted below, shows the successful case. + +![sync-mss-receipt](/img/sync-mss-receipt.png) + +1. For each successful MSS_SignatureResp the AP can request an MSS_ReceiptReq by passing the same MSSP_TransID and same MSISDN from the MSS_SignatureResp and defining message to be displayed to the End-User. +2. MID backend checks the credentials. +3. MID sends a receipt request to the Mobile ID application on the mobile device. +4. The Mobile ID application displays the message to the End-User. +5. The user press “ok” or “cancel” which trigger MSS Receipt response. +6. The Receipt response is sent to Mobile ID. +7. MID sends MSS_ReceiptResp to the AP. + + +#### MSS Receipt Request + +At this point in time, AP has received the MSS_SignatureResp with the `MSSP_TransID="h4iof"`, which is the transaction identifier that need to be set in the MSS_ReceiptReq message. +Moreover, the AP must set the LANGUAGE (one of EN, DE, FR, IT) which is usually the same as used in the preceding signature. +NOTE: The lines highlighted in pink is an optional extension to get a more detailed receipt response. This extension is currently supported by the SIM method only! Please remove these lines in case of the App method. + + + +::: code-group + +```json [REST/json] + +{ + "MSS_ReceiptReq": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T12:00:00.000+01:00" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MSSP_TransID": "h4iof", + "MajorVersion": "1", + "Message": { + "Data": "RECEIPT_MESSAGE", + "Encoding": "UTF-8", + "MimeType": "text/plain" + }, + "MinorVersion": "1", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "Status": { + "StatusCode": { + "Value": "100" + }, + "StatusDetail": { + "ReceiptRequestExtension": { + "ReceiptMessagingMode": "synch", + "ReceiptProfile": { + "Language": "LANGUAGE", + "ReceiptProfileURI": "http://mss.swisscom.ch/synch" + }, + "UserAck": "true" + } + } + } +} } + + + + +``` + +```xml [SOAP/xml] + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + + + + + + http://mss.swisscom.ch/synch + + + + + RECEIPT_MESSAGE + + + + + + + + + +``` + +::: + + +#### MSS Receipt Response + +::: info +The `ReceiptResponseExtension` highlighted in pink is an optional extension to get a more detailed receipt response. The response will only contain this part if `ReceiptRequestExtension` was requested in the Receipt Request message. This extension is currently supported by the SIM method only. The table below describes different `ReceiptResponseExtension` related scenarios. +::: + +| Response scenario | UserAck | User Response | Fault Message | +|-------------------|---------|----------------|---------------| +| No user response could be received within 80 seconds. It is unknown if the user got the receipt message. | false | N/A | N/A | +| User accepted the receipt message | true | "OK" | N/A | +| User cancelled the receipt message | true | "CANCEL" | "User Cancelled the request" | +| The receipt message was displayed for 60 seconds but user did not respond | true | "TIMEOUT" | + +::: code-group + +```json [REST/json] +{ + "MSS_ReceiptResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2015-01-01T11:00:00.100Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "1", + "MinorVersion": "1", + "Status": { + "StatusCode": { + "Value": "100" + }, + "StatusDetail": { + "ReceiptResponseExtension": { + "ClientAck": "false", + "NetworkAck": "false", + "ReceiptMessagingMode": "synch", + "UserAck": "true", + "UserResponse": "{\"status\":\"OK\"}" + } + }, + "StatusMessage": "REQUEST_OK" + } + } +} + + + +``` + +```xml [SOAP/xml] + + + + + + + + http://mid.swisscom.ch/ + + + + + REQUEST_OK + + + + + + + + + + + + +``` + +::: + +### Encrypted MSS Receipts + +**Marked as obsolete** - We currently no longer support encrypted Signature Receipts. + + +## MSS Profile Query + +An AP may use this operation to check the Mobile ID status and signature capabilities of a specific user (MSISDN) without requiring end-user interaction. Typically, an Application Provider would like to get the mobile signature profile capabilities before requesting a signature. + +The AP can use a Profile Query request as depicted below. + +![mss-profile-query](/img/mss-profile-query.png) + +1. Before to send a signature request for authentication, the AP validates the status and signature profile capabilities of a Mobile ID user by sending an MSS_ProfileReq request to Mobile ID +2. MSSP checks the user status and signature capabilities +3. In case of an active user, it retrieves the Signature Profiles of the end-user and sends back an MSS_ProfileResp. Otherwise, if the user is not active, the server sends back a fault response that may contain additional details about the user status. + +### Endpoint + +::: code-group +```bash [REST] +/rest/service/profile +``` +```bash [SOAP] +/soap/services/MSS_ProfilePort +``` +::: + +### MSS Profile Query Request + +The lines highlighted in pink are optional Profile Query Extension parameters (see section [MSS Profile Query Request Extensions](/rest-api-guide/mobile-id-api#mss-profile-query-request-extensions)). + +::: code-group + +```json [REST/json] +{ + "MSS_ProfileReq": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_PWD": "not-needed", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T12:00:00.000+01:00" + }, + "MSSP_Info": { + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "2", + "MinorVersion": "0", + "MobileUser": { + "MSISDN": "MOBILE_NUMBER" + }, + "Params": "sscds state certs pinstatus rcstatus aastatus carddetails" + } +} + + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + MOBILE_NUMBER + + sscds state certs pinstatus rcstatus aastatus + + + + + + +``` + +::: + +#### MSS Profile Query Request Extensions +Optional Profile Query Extension parameters can be set in the Profile Query request message to get additional information in the Profile Query response message. + +| Params value | Profile Query response content | +|--------------|--------------------------------| +| `sscds` | A list of all available Secure Signature Creation Devices of the user | +| `state` | User account state details | +| `certs` | X.509 mobile user certificate binary content and details, including subject name. **Note**: The subject name contains the user's unique MID serial number value. | +| `pinstatus` | Mobile ID SIM card's Mobile ID PIN status | +| `rcstatus` | User's recovery code status (has it been created: true or false) | +| `aastatus` | Auto-Activation status (is it enabled: true or false), see section 5 | +| `carddetails` | Mobile ID SIM card details, for example the Mobile Network Operator | + + +### MSS Profile Query Response + +The lines highlighted in pink are optional Profile Query Extension parameters (see section [MSS Profile Query Request Extensions](/rest-api-guide/mobile-id-api#mss-profile-query-request-extensions)) + + +::: code-group + +```json [REST/json] + +{ + "MSS_ProfileResp": { + "AP_Info": { + "AP_ID": "yourAP_ID", + "AP_TransID": "REF0101120000", + "Instant": "2015-01-01T11:00:00.000Z" + }, + "MSSP_Info": { + "Instant": "2015-01-01T11:00:00.100Z", + "MSSP_ID": { + "URI": "http://mid.swisscom.ch/" + } + }, + "MajorVersion": "2", + "MinorVersion": "0", + "SignatureProfile": [ + "SIGNATURE_PROFILE_1", + "SIGNATURE_PROFILE_2", + "SIGNATURE_PROFILE_3", + "SIGNATURE_PROFILE_*" + ], + "Status": { + "StatusCode": { + "Value": "100" + }, + "StatusDetail": { + "ProfileQueryExtension": { + "MobileUser": { + "AutoActivation": false, "RecoveryCodeCreated": true + }, + "Sscds": { + "App": [ + { + "MobileUserCertificate": [ + { + "Algorithm": "RSA", + "State": "ACTIVE", + "X509Certificate": [ + "X509_BASE64_CERT_USER", "X509_BASE64_CERT_CA" + ], + "X509SubjectName": [ + "X509_BASE64_SUBJECT_USER", "X509_BASE64_SUBJECT_CA" + ] + } + ], + "PinStatus": { + "Blocked": false + }, + "State": "ACTIVE" + } + ], + "Sim": { + "CardDetails": { + "Mcc": "228", "Mnc": "01", "Network": "Swisscom" + }, + "MobileUserCertificate": [ + { + "Algorithm": "RSA", + "State": "INACTIVE", + "X509Certificate": [ + "X509_BASE64_CERT_USER", "X509_BASE64_CERT_CA" + ], + "X509SubjectName": [ + "X509_BASE64_SUBJECT_USER", "X509_BASE64_SUBJECT_CA" + ] + }, + { + "Algorithm": "EC", + "State": "INACTIVE", + "X509Certificate": [ + "X509_BASE64_CERT_USER", "X509_BASE64_CERT_CA" + ], + "X509SubjectName": [ + "X509_BASE64_SUBJECT_USER", "X509_BASE64_SUBJECT_CA" + ] + } + ], + "PinStatus": { + "Blocked": false + }, + "State": "INACTIVE" + } + } + } + }, + "StatusMessage": "REQUEST_OK" + } + } +} + +``` + +```xml [SOAP/xml] + + + + + + + + + http://mid.swisscom.ch/ + + + + SIGNATURE_PROFILE_1 + + + SIGNATURE_PROFILE_2 + + + SIGNATURE_PROFILE_3 + + + SIGNATURE_PROFILE_* + + + + REQUEST_OK + + + + + + INACTIVE + + + X509_BASE64_CERT_USER + X509_BASE64_SUBJECT_USER + X509_BASE64_CERT_CA + X509_BASE64_SUBJECT_CA + + + X509_BASE64_CERT_USER + X509_BASE64_SUBJECT_USER + X509_BASE64_CERT_CA + X509_BASE64_SUBJECT_CA + + + 228 + 01 + Swisscom + + + + ACTIVE + + + X509_BASE64_CERT_USER + X509_BASE64_SUBJECT_USER + X509_BASE64_CERT_CA + X509_BASE64_SUBJECT_CA + + + + + + + + + + + + + +``` + +::: + + + +--- + +## REST API Best Practices + +Source: https://docs.mobileid.ch/rest-api-guide/best-practices.html + +# Best Practices + +This page provides guidelines for constructing requests, validating responses, and handling errors when integrating with the Mobile ID API. + +::: tip Java Reference Client +For Java projects, use the official [Java Reference Client](/rest-api-guide/java-reference-client) — a production-ready library that implements all of these best practices out of the box. +::: + +## MSS Signature + +### Signature Request + +When constructing an MSS Signature request, the following best-practice guidelines should be followed: + +1. **Define a unique `AP_TransID` (Transaction ID)** + Each signature request must have a unique transaction identifier. + +2. **Set the current time for `Instant` (with time zone)** + The `Instant` parameter must include time zone information and must not deviate excessively from the Mobile ID Service's current time; otherwise, a fault response with sub-code 101 will be returned. + - **Example:** `2020-01-01T12:00:00.000+01:00` + - Must conform to the [W3C `xs:dateTime`](https://www.w3.org/TR/xmlschema-2/#dateTime) format. + +3. **Ensure uniqueness across the triplet `(AP_ID, AP_TransID, Instant)`** + The combination of these three fields must be unique for every transaction. + Duplicate triplets are rejected. + +4. **Specify `MSISDN` in international format** + The user's phone number must follow international ([E.164](https://www.itu.int/rec/T-REC-E.164/)) notation without spaces. + A leading “+” is allowed but optional. + - **Example:** `+41791234567` + +5. **Set a valid `UserLang` value** + The value must be one of the supported languages — EN, DE, FR, or IT — and must match the language used in the DataToBeDisplayed (`DTBD`) message. + +6. **Define the `DataToBeDisplayed` (DTBD) message** + The text shown on the user’s mobile device must comply with the following guidelines: + - Encoded in UTF-8. + - Should include a unique transaction reference (e.g., timestamp, customer ID, contract ID). + - **Length limits:** + - Maximum 239 characters if all characters are in the standard [GSM 03.38](https://en.wikipedia.org/wiki/GSM_03.38) character set. + - If any character falls outside this set (e.g., the lowercase cedilla "ç"), the maximum length reduces to 119 characters. + - Keep the message as short and user-friendly as possible. + + **Example DTBD:** + > `Bank ACME: Proceed with the login? (TXN-3D5K)` + + +### Signature Response + +After receiving the MSS Signature Response, the client (Application Provider – AP) must perform proper response validation to ensure authenticity, integrity, and consistency with the original request. + +The key validation aspects are as follows: + +1. **Match Request and Response Identifiers** + - Verify that the `AP_TransID` and `MSISDN` values in the response are identical to those sent in the original request. + - Any mismatch should be treated as an invalid response and rejected. + +2. **Validate the Mobile User’s X.509 Certificate** + - Ensure the user certificate chains up to a trusted root CA contained in your local TrustStore. + - The client should only trust certificates that link to a trust anchor matching the expected Swisscom Mobile ID CA. + - Your TrustStore should only contain the relevant root CA certificate (see **[Root CA Certificates](/rest-api-guide/root-ca-certs.md)**). + +3. **Verify the Digital Signature** + - Confirm that the received digital signature is cryptographically valid. + - The signed content must correspond exactly to the `DataToBeDisplayed (DTBD)` text from the earlier signature request. + - The client must be capable of validating both RSA and ECDSA signatures. + +4. **(Optional) Validate the Mobile ID Serial Number** + - For the highest level of assurance and a fully strong two-factor authentication process, validate the Mobile ID serial number as described in **[Serial Number Validation](/rest-api-guide/best-practices#serial-number-validation)**. + +5. **Implement Proper Fault and Status Handling** + - Handle all status and fault codes using structured exception handling logic to ensure stable, predictable behavior of the client application. + +::: warning Important +Certificate revocation checks are not recommended. +Mobile ID user certificates are never revoked individually — the Mobile ID service backend manages account validity and state directly. +::: + + +### Signature Concurrency Control + +This section describes the behavior of the Mobile ID Service when an Application Provider (AP) submits a new MSS Signature request while another signature transaction is already in progress for the same MSISDN and the same authentication method. + +Concurrency handling depends on whether the request targets the SIM method or the Mobile ID App method. + +##### SIM Method Concurrency +If both signature requests target the SIM-based authentication method, and the first signature transaction is still in progress, the second request is rejected immediately. + +- **Fault Code:** `406 / PB_SIGNATURE_PROCESS` +- **Description:** The subscriber already has an active signature operation in process. +- See **[Status and Fault Codes](/rest-api-guide/status-fault-codes)** for detailed fault code definitions. + +##### App Method Concurrency +If both requests target the Mobile ID App-based authentication method, the behavior is different: + +- The existing first signature transaction is canceled automatically by the backend. +- The second signature request is then displayed on the mobile device via the Mobile ID App. + +- **Fault Code (cancellation of first transaction):** `401 / USER_CANCEL` +- See **[Status and Fault Codes](/rest-api-guide/status-fault-codes)** for further information. + +## Serial Number Validation + +With an MSS Signature response, you will get signature data and the mobile user's X.509 certificate, which contains the public key required to validate the signature data. + +That X.509 certificate's Subject Name (Distinguished Name) contains a unique Mobile ID serial number. + +Example subject name with the serial number: + +```bash + +cn=midcheptod58qe59:pn,serialnumber=midcheptod58qe59,pseudonym=midcheptod58qe59 +``` + + +For highest level of assurance and a truly strong two-factor-authentication process, an AP should store this value at the first signature and then verify every subsequent signature response if that serial number value still matches. + +::: warning +If the value does not match anymore, it means that the user re-activated their account without a valid recovery option. In such case (serial number mismatch) the 2nd factor (knowledge/inherence) is not assured. +::: + +## Timeout Value + +::: info Recommended Timeout Values +Use the reference values below to set an appropriate transaction timeout: + +| MSS Operation | Transaction Timeout | Client Connection Timeout | +|---------------|---------------------|---------------------------| +| Synchronous MSS Signature | 80 seconds for Mobile ID SIM
40 seconds for Mobile ID App | 90 seconds
50 seconds | +| Asynchronous MSS Signature | 80 seconds for Mobile ID SIM
40 seconds for Mobile ID App | 10 seconds | +| MSS Status Query | - | 10 seconds | +| MSS Receipt | - | 90 seconds | +| MSS Profile Query | - | 10 seconds | + +::: + +## Mobile ID FAQ + +Please visit [https://mobileid.ch/en/faq](https://mobileid.ch/en/faq) for a list of frequently asked questions about Mobile ID + +## Mobile ID Service Health Check + +The recommended way to check the service health status is to send a synchronous MSS Signature request with the MSISDN value set to +41000000000 and DTBD set to Heartbeat. + +The Mobile ID service health check is successful if a fault code 101/WRONG_PARAM with Detail value Illegal msisdn is returned, as shown in the example: + +### SOAP/XML + +```xml +.. + + + soapenv:Sender + + mss:_101 + + + + WRONG_PARAM + + + Illegal msisdn + + +.. +``` + + +### REST/JSON + +```json +.. + +{ + "Fault": { + "Code": { + "SubCode": { + "Value": "_101", + "ValueNs": "http://uri.etsi.org/TS102204/v1.1.2#" + }, + "Value": "Sender", + "ValueNs": "http://www.w3.org/2003/05/soap-envelope" + }, + "Detail": "Illegal msisdn", + "Reason": "WRONG_PARAM" + } +} + +.. +``` + + +## Client Libraries + +The [MobileID-Strong-Authentication](https://github.com/MobileID-Strong-Authentication) GitHub organisation provides reference implementations and examples for building Mobile ID clients. + +| Library | Language | Description | +|---------|----------|-------------| +| [mobileid-client-java](https://github.com/MobileID-Strong-Authentication/mobileid-client-java) | Java 8+ | Official reference implementation for REST and SOAP APIs | + +See the [Java Reference Client](/rest-api-guide/java-reference-client) page for setup instructions, code examples, and usage patterns. + +--- + +## REST API Auto Activation + +Source: https://docs.mobileid.ch/rest-api-guide/auto-activation.html + +# Auto Activation +## Introduction + +Auto Activation is an optional feature for Application Providers (APs) that can greatly improve the user experience for Mobile ID SIM authentications. + +- **Applicable to**: SIM authentication only (not relevant for Mobile ID App authentications). +- **Default state**: Disabled by default, but can be enabled per Application Provider. + +### How it works + +Usually, a brand new Mobile ID SIM card must be activated once on the MyMobileID Portal. During this activation, the user sets their personal Mobile ID PIN and a signing key is created on the SIM card. + +With Auto Activation enabled, a Signature Request to a user with an **inactive** Mobile ID SIM will invoke an implicit activation process during the ongoing signature transaction. This achieves: + +- A successful Mobile ID activation **and** +- A successful authentication (Signature Response) at the same time + +From the AP perspective, the user simply has a successful authentication -- there is no difference whether the user was auto-activated during the transaction or not. + +::: tip +Auto Activation feature can successfully prevent a fault sub-code 404 (this fault code means that the user did not yet activate their Mobile ID SIM card) which can happen when an AP attempts to do a Mobile ID authentication with a user that has an inactive Mobile ID SIM card. +::: + +## How to implement this feature +To enable the Auto Activation feature for an Application Provider (AP), the AP must ensure that the user has accepted the Mobile ID specific terms & conditions prior to proceeding with the auto activation steps. + +An AP may use the Profile Query Extensions (see [Section MSS Profile Query](/rest-api-guide/mobile-id-api.html#mss-profile-query)) to know if a signature request to a user will invoke auto activation or not. However, an AP does not necessarily need to know that. + +Please speak to your Swisscom contact if you wish to get this feature enabled for your AP account. Optionally we can also setup specific test SIM cards, which allows an AP to test this feature (because those test SIM cards will be configured to always trigger the auto activation). + + +## User Perspective +From a user perspective, the steps displayed on the mobile device look very similar, if you compare the signature process of an active Mobile ID SIM vs. the process of an inactive Mobile ID SIM. + +![auto-activation-user-perspective](/img/auto-activation-user-perspective.png) + +::: info +In case of a successful auto activation, the Mobile ID server sends a Text SMS to the user, to remind the user to create a Mobile ID recovery code [24](#24). +::: + +::: details References and Footnotes +24. Each time a user completes the Mobile ID activation process, they will receive a code that enables them to recover Mobile ID and maintain their existing pairings to service providers, if you lose your phone, change SIM cards or switch to an e-SIM card. See https://mobileid.ch/recovery [↩](#a17) +::: + + + + + +--- + +## REST API Status and Fault Codes + +Source: https://docs.mobileid.ch/rest-api-guide/status-fault-codes.html + +# Status and Fault Codes +## Overview + +### Status Codes (Success) + +| Code | Message | Description | Applicable To | +|------|---------|-------------|---------------| +| 100 | REQUEST_OK | The request from the AP has been accepted. | Signature, Receipt, Profile | +| 500 | SIGNATURE | The MSS Signature transaction was successful. | Signature, Status Query | +| 501 | REVOKED_CERTIFICATE | The Mobile ID user's x509 certificate has been revoked. The user must re-activate the account on the Mobile ID self-care portal. | Signature, Status Query | +| 502 | VALID_SIGNATURE | The MSS Signature transaction was successful. | Signature, Status Query | +| 503 | INVALID_SIGNATURE | The MSS Signature transaction failed due to invalid signature data. The user may try to re-activate the account on the Mobile ID self-care portal. It may be required to replace the SIM card. | Signature, Status Query | +| 504 | OUTSTANDING_TRANSACTION | The MSS Signature transaction is outstanding. The AP must try again later. | Status Query | + +### Fault Codes (Error) + +| Code | Message | Description | Applicable To | +|------|---------|-------------|---------------| +| 101 | WRONG_PARAM | The AP's request contains wrong parameters. | All | +| 102 | MISSING_PARAM | The AP's request has missing parameters. | All | +| 103 | WRONG_DATA_LENGTH | The AP's request contains a DTBD message that is exceeding the max. allowed length. | Signature, Receipt | +| 104 | UNAUTHORIZED_ACCESS | AP is not authorized to access the Mobile ID API. This is typically due to a wrong AP_ID value or missing X509 client certificate. | All | +| 105 | UNKNOWN_CLIENT | Either the MSISDN is unknown to the MID service, or the MSISDN is an app-only user and the AP is not authorized to use the app method. | Signature, Receipt, Profile | +| 107 | INAPPROPRIATE_DATA | The AP's request was not accepted due to inappropriate data. Typically, the DTBD message does not contain the mandatory prefix string that is a unique string for each AP. | Signature, Receipt | +| 108 | INCOMPATIBLE_INTERFACE | The AP's request contains bad data. Typically, a wrong MajorVersion or MinorVersion value has been set in the request. | All | +| 109 | UNSUPPORTED_PROFILE | Either the AP has specified an MSS signature profile value that the MSSP does not support or the AP is not authorized to use the Signature Profile. | Signature | +| 208 | EXPIRED_TRANSACTION | The transaction timed out. The AP may try again. | Signature, Status Query, Receipt | +| 209 | OTA_ERROR | A problem related to the MSSP internal Over-The-Air (OTA) communication with the Mobile ID user's SIM. Typically, there is a temporary problem with SMS communication. | Signature, Status Query | +| 401 | USER_CANCEL | The user cancelled the request at the mobile phone. | Signature, Status Query | +| 402 | PIN_NR_BLOCKED | The Mobile ID PIN of the SIM method is blocked. The user must re-activate the Mobile ID SIM card on the Mobile ID self-care portal. | All | +| 403 | CARD_BLOCKED | The Mobile ID user is currently suspended. Please contact Swisscom Support. | All | +| 404 | NO_KEY_FOUND | The Mobile ID user exists but is not in an active state. The user must activate the account on the Mobile ID self-care portal. | All | +| 406 | PB_SIGNATURE_PROCESS | A signature transaction is already ongoing. Please try again later. | Signature, Status Query | +| 422 | NO_CERT_FOUND | The Mobile ID user exists but is not in an active state. The user must activate the account on the Mobile ID self-care portal. | All | +| 900 | INTERNAL_ERROR | An internal error on MSSP has occurred. Please try again later or contact Swisscom Support, if the problem persists. | All | + + +## Testing Status and Fault Codes + +Specific MSISDNs are available to test different type of response status and fault codes. By placing a request to one of this number the related status or fault code will be raised. The following MSISDN structure is used for testing fault codes, which might help a developer to test the error handling of their Mobile ID client. + +- `+41000092` - Use one of the 3-digit fault sub-code values listed in the [Fault Codes](#fault-codes-error) table above. + +On the other hand, a successful Mobile ID signature response can be tested by using one of the two MSISDNs listed below, which might help with CI/CD pipelines that include automated regression testing with Mobile ID authentications. However, your account will require specific permissions to be able to use the test-MSISDNs for successful Mobile ID responses. Please ask your Swisscom contact if you need this permission. + +- `41700092501` – This number returns a successful Mobile ID signature response based on an EC key +- `41700092502` - This number returns a successful Mobile ID signature response based on an RSA key + +## Test-MSISDN Overview + +| Request Test-MSISDN | Fault Code | Reason Message | Detail Message | +|---------------------|------------|-----------------|-----------------| +| 41000092101 | 101 | WRONG_PARAM | Error among the arguments of the request | +| 41000092102 | 102 | MISSING_PARAM | An argument in the request is missing | +| 41000092103 | 103 | WRONG_DATA_LENGTH | The DataToBeSigned are too large. Limitations are due to the Mobile Signature technology implemented by the MSSP. | +| 41000092104 | 104 | UNAUTHORIZED_ACCESS | The AP is unknown, or the client authentication failed, or the AP asks for an additional service for which it has not subscribed. | +| 41000092105 | 105 | UNKNOWN_CLIENT | MSISDN is unknown | +| 41000092107 | 107 | INAPPROPRIATE_DATA | DTBD matching failed | +| 41000092108 | 108 | INCOMPATIBLE_INTERFACE | The minor version and/or major version parameters are inappropriate for the receiver of the message. | +| 41000092109 | 109 | UNSUPPORTED_PROFILE | The user does not support this Mobile Signature Profile | +| 41000092208 | 208 | EXPIRED_TRANSACTION | Transaction Expiry date has been reached or Time out has lapsed. | +| 41000092209 | 209 | OTA_ERROR | The MSSP has not succeeded to contact the end-user's mobile equipment Bad connection...) | +| 41000092401 | 401 | USER_CANCEL | User cancelled the request | +| 41000092402 | 402 | PIN_NR_BLOCKED | PIN of the mobile user is blocked | +| 41000092403 | 403 | CARD_BLOCKED | Mobile user account has state INACTIVE or no SIM assigned | +| 41000092404 | 404 | NO_KEY_FOUND | Mobile user account needs to be activated | +| 41000092406 | 406 | PB_SIGNATURE_PROCESS | Signature request already in progress. | +| 41000092422 | 422 | NO_CERT_FOUND | Certificate is expired | +| 41000092900 | 900 | INTERNAL_ERROR | Unknown Error | + +For example, a Profile Query request with MSISDN +41000092401 will result in a fault 401 as shown below: + +```json +{ + "Fault": { + "Code": { + "SubCode": { + "Value": "_401", + "ValueNs": "http://uri.etsi.org/TS102204/v1.1.2#" + }, + "Value": "Receiver", + "ValueNs": "http://www.w3.org/2003/05/soap-envelope" + }, + "Detail": "User cancelled the request", + "Reason": "USER_CANCEL" + } +} +``` + + + +--- + +## REST API Root CA Certificates + +Source: https://docs.mobileid.ch/rest-api-guide/root-ca-certs.html + +# Root CA Certificates + +There are two different scenarios (described in the two chapters below) to consider, where x.509 certificates are involved. Since they do not have the same root CA, you must ensure that your client's TrustStore contains all involved "Root CA" certificates. + + +## X509 Server Certificate + +As described in [Section Mutual Authentication](/rest-api-guide/app-provider-client-integration.html#mutual-authentication), the Mobile ID server's x.509 certificate that is used in the mutual SSL/TLS authentication process is a SwissSign certificate. + +You can download the "SwissSign Gold CA - G2" certificate from the SwissSign site: +[https://www.swisssign.com/en/support/faq.html](https://www.swisssign.com/en/support/faq.html) + +| SHA-1 Fingerprint | +|-------------------| +| D8 C5 38 8A B7 30 1B 1B 6E D4 7A E6 45 25 3A 6F 9F 1A 27 61 | + + +## User X509 Certificate + +As described in [Section MSS Signature](/rest-api-guide/mobile-id-api.html#mss-signature), the main scenario is a strong authentication, where the AP receives a signature response, which includes the signature object and the mobile user's x.509 certificate (public key). The AP should validate the signature as well as the x.509 certificate's trust chain. + +The figure below depicts the Mobile ID Certificate Chain. The User Certificate (End Entity Certificate) is issued by the Intermediate Certificate. The Intermediate Certificate is issued by the Root Certificate. + +Usually, a client's TrustStore contains the Root Certificate only, the so-called trust anchor. Having the root certificate in the client's TrustStore, the whole certificate chain can be validated, including the Mobile ID user's end entity certificate. + +![end-entity-certificate](/img/end-entity-certificate.svg) + +The Mobile ID End Entity Certificate is either based on the Root Certificate `Swisscom Root CA 4` or on the older Root Certificate `Swisscom Root CA 2`. + +You can download the "Swisscom Root CA 4" certificate from the Swisscom Digital Certificate Service site: +[https://aia.swissdigicert.ch/sdcs-root4.crt](https://aia.swissdigicert.ch/sdcs-root4.crt) + +| SHA-1 Fingerprint | +|-------------------| +| B9 82 1B 0C 87 7D 30 24 DD 6A 8F 6E 44 3E F5 38 8E 53 16 1B | + +You can download the "Swisscom Root CA 2" certificate from the Swisscom Digital Certificate Service site: +[https://aia.swissdigicert.ch/sdcs-root2.crt](https://aia.swissdigicert.ch/sdcs-root2.crt) + +| SHA-1 Fingerprint | +|-------------------| +| 77 47 4F C6 30 E4 0F 4C 47 64 3F 84 BA B8 C6 95 4A 8A 41 EC | + +::: warning Important +Please ensure that your Mobile ID client's TrustStore contains both the old Root Certificate `Swisscom Root CA 2` as well as the new Root Certificate `Swisscom Root CA 4`. +::: + + + +--- + +## REST API Create Client Certificates + +Source: https://docs.mobileid.ch/rest-api-guide/create-client-certs.html + +# Create Client Certificates + +Below are examples how to create a self-signed certificate with OpenSSL and Java Keytool. + +::: info Remarks +- Use any meaningful value for the distinguished name (CN/O/C values). +- Use SHA-256 as shown below. +- Validity can be set to 3 or 5 years. However, the validity is never checked by Mobile ID. +- The examples create a self-signed certificate (easy to make, no cost). +- The client certificate's Enhanced Key Usage must include Client Authentication (OID 1.3.6.1.5.5.7.3.2). +::: +::: warning +Provide the resulting `mycert.crt` file to Swisscom and keep your private key / keystore files (`*.jks`, `*.p12`, `*.key`) securely stored. Never share your private key. +::: + +## OpenSSL + +### Generate Key & Create CSR + +```bash +$ openssl req -new -newkey rsa:4096 -nodes -rand /dev/urandom \ + -keyout mycert.key -out mycert.csr -sha256 \ + -subj '/CN=mobileid.company.ch/O=Company/C=CH' + +``` + +### Self-Sign Certificate + +Create a small extension file `ext.cnf` that adds the required Client Authentication Extended Key Usage: + +```ini +[v3_req] +extendedKeyUsage = clientAuth +``` + +Then self-sign the certificate: + +```bash +$ openssl x509 -req -days 1825 -sha256 -extfile ext.cnf -extensions v3_req \ + -in mycert.csr -signkey mycert.key -out mycert.crt +``` + + +### Convert To PKCS#12 + +Optionally, if you need a PKCS#12 file you can convert the Key and Certificate with this command: + +```bash +$ openssl pkcs12 -export -in mycert.crt -inkey mycert.key -out mycert.p12 +``` + + +## Java KeyTool + +### Generate Key & Export Certificate + +```bash +$ keytool -genkey -alias -keyalg RSA -keysize 4096 -validity 1825 \ + -dname "CN=mobileid.company.ch,O=Company,C=CH" -keystore mycert.jks + +$ keytool -export -alias -keystore mycert.jks -file mycert.crt +``` +::: tip +If your JDK supports it, add an Extended Key Usage for client auth during key generation (syntax depends on JDK version), e.g. `-ext "ExtendedKeyUsage=clientAuth"`. Otherwise, you can generate a CSR with keytool and self-sign it with OpenSSL using the ext.cnf shown above. +::: + + +--- + +## REST API Health Status Service + +Source: https://docs.mobileid.ch/rest-api-guide/health-status.html + +# Health Status Service + +The Mobile ID Health Status Service is a microservice for retrieving health state details about the MobileID authentication service. + +- **Based on**: Real end-to-end authentication tests, checked every few minutes +- **Scope**: Different telecommunications providers, IP+ and EC endpoints, and the geofencing service +- **Cost**: Free of charge + +For more information, please visit https://digital.swisscom.com/products/mobile-id + +## What is Monitored + +- **Telecommunications Providers**: Mobile ID SIM cards from Swisscom, Sunrise, Salt +- **Mobile ID App**: The Mobile ID mobile application +- **End-to-end tests**: Real Mobile ID tests responded by special robotic equipment at different physical locations + +## Health Status Levels + +Each test objective will have one of three possible status levels: + +- **SUCCESS** + All tests of that objective (e.g. Operator "Swisscom) are currently successful. + +- **WARNING** + Some (but not all) tests of that objective failed for 1 or more times in a row. However, some tests of that objective are still working fine. + +- **ERROR** + All tests of that objective failed. Mobile ID operation team has been alerted to check the system. + +--- + +## REST API Java Reference Client + +Source: https://docs.mobileid.ch/rest-api-guide/java-reference-client.html + +# Java Reference Client + +The [`mobileid-client-java`](https://github.com/MobileID-Strong-Authentication/mobileid-client-java) repository provides the official Java reference implementation for the Mobile ID REST API (and SOAP API). It is designed for Java 8+ projects that need secure authentication and authorization using Swisscom Mobile ID. + +The client library handles all the complexity of mTLS connections, request construction, response parsing, async polling, and signature validation — letting you focus on integrating Mobile ID into your application. + +## Features + +- **Synchronous and asynchronous** signature requests with polling +- **Signature receipt** delivery to mobile users +- **Profile queries** (account status, capabilities, certificate info) +- **Signature validation** (certificate path, signature integrity, DTBS matching) +- **Thread-safe** — create once, reuse across your application +- **Connection pooling** for efficient resource usage +- **HTTP proxy support** with optional authentication + +## Getting the Library + +### Maven + +```xml + + ch.mobileid.mid-java-client + mid-java-client-rest + 1.5.7 + +``` + +### Gradle + +```groovy +dependencies { + implementation 'ch.mobileid.mid-java-client:mid-java-client-rest:1.5.7' +} +``` + +::: tip +Check the [Releases page](https://github.com/MobileID-Strong-Authentication/mobileid-client-java/releases) for the latest version. +The library is also available on [Maven Central](https://search.maven.org/search?q=ch.mobileid). +::: + +## Quick Start + +### 1. Configure the Client + +Create a `ClientConfiguration` with your AP credentials and TLS settings. This is done **once** per application lifetime. + +```java +import ch.swisscom.mid.client.config.*; +import ch.swisscom.mid.client.impl.MIDClientImpl; +import ch.swisscom.mid.client.MIDClient; + +ClientConfiguration config = new ClientConfiguration(); +config.setProtocolToRest(); +config.setApId("mid://id-received-from-swisscom"); +config.setApPassword("pass-received-from-swisscom"); + +// Service endpoint +UrlsConfiguration urls = config.getUrls(); +urls.setAllServiceUrlsTo( + DefaultConfiguration.DEFAULT_INTERNET_BASE_URL + + DefaultConfiguration.REST_ENDPOINT_SUB_URL); + +// mTLS client certificate +TlsConfiguration tls = config.getTls(); +tls.setKeyStoreFile("keystore.jks"); +tls.setKeyStorePassword("secret"); +tls.setKeyStoreKeyPassword("secret"); +tls.setKeyStoreCertificateAlias("mid-cert"); +tls.setTrustStoreFile("truststore.jks"); +tls.setTrustStorePassword("secret"); + +// HTTP timeouts +HttpConfiguration http = config.getHttp(); +http.setConnectionTimeoutInMs(20_000); +http.setResponseTimeoutInMs(100_000); + +// Create the client (thread-safe, reusable) +MIDClient client = new MIDClientImpl(config); +``` + +::: warning +Call `client.close()` when your application shuts down to properly release resources. Do **not** close it after each request. +::: + +### 2. Request a Synchronous Signature + +```java +import ch.swisscom.mid.client.model.*; + +SignatureRequest request = new SignatureRequest(); +request.setUserLanguage(UserLanguage.ENGLISH); +request.getDataToBeSigned().setData("Bank ACME: Confirm login (REF-8F2K)"); +request.getMobileUser().setMsisdn("41791234567"); +request.setSignatureProfile(SignatureProfiles.DEFAULT_PROFILE); +request.addAdditionalService(new GeofencingAdditionalService()); + +SignatureResponse response = client.requestSyncSignature(request); +``` + +### 3. Request an Asynchronous Signature with Polling + +For better control and user experience, use the async flow with status polling: + +```java +SignatureRequest request = new SignatureRequest(); +request.setUserLanguage(UserLanguage.ENGLISH); +request.getDataToBeSigned().setData("Bank ACME: Confirm login (REF-8F2K)"); +request.getMobileUser().setMsisdn("41791234567"); +request.setSignatureProfile(SignatureProfiles.DEFAULT_PROFILE); + +SignatureResponse response = client.requestAsyncSignature(request); + +// Poll until the signature completes or fails +while (response.getStatus().getStatusCode() == StatusCode.REQUEST_OK || + response.getStatus().getStatusCode() == StatusCode.OUTSTANDING_TRANSACTION) { + Thread.sleep(5000); + response = client.pollForSignatureStatus(response.getTracking()); +} + +if (response.getStatus().getStatusCode() == StatusCode.SIGNATURE) { + // Signature successful — validate and proceed +} +``` + +### 4. Send a Receipt + +After a successful signature, send a receipt message to the mobile user: + +```java +ReceiptRequest receiptRequest = new ReceiptRequest(); +receiptRequest.getMessageToBeDisplayed().setData("Login completed successfully"); +receiptRequest.setStatusCode(StatusCode.REQUEST_OK); +receiptRequest.addReceiptRequestExtension(); + +ReceiptResponse receiptResponse = client.requestSyncReceipt( + response.getTracking(), receiptRequest); +``` + +### 5. Query a User Profile + +Check if a user is registered and what methods are available: + +```java +ProfileRequest request = new ProfileRequest(); +request.getMobileUser().setMsisdn("41791234567"); +request.setExtensionParamsToAllValues(); + +ProfileResponse response = client.requestProfile(request); +``` + +## Signature Validation + +After acquiring a mobile signature, you should validate it to ensure the signing certificate is valid, the certificate path is trusted, and the signed data matches what was requested. + +```java +import ch.swisscom.mid.client.crypto.*; + +// Configure the trust store for certificate path validation +SignatureValidationConfiguration svConfig = new SignatureValidationConfiguration(); +svConfig.setTrustStoreFile("signature-validation-truststore.jks"); +svConfig.setTrustStoreType("jks"); +svConfig.setTrustStorePassword("secret"); + +// Validate the signature +SignatureValidator validator = new SignatureValidatorImpl(svConfig); +SignatureValidationResult result = validator.validateSignature( + response.getBase64Signature(), + request.getDataToBeSigned().getData(), + null +); + +if (result.isValidationSuccessful()) { + String midSerialNumber = result.getMobileIdSerialNumber(); + // Store and compare the serial number for strong 2FA assurance +} else { + // Inspect what failed + System.out.println("Cert path valid: " + result.isSignerCertificatePathValid()); + System.out.println("Cert valid: " + result.isSignerCertificateValid()); + System.out.println("Signature valid: " + result.isSignatureValid()); + System.out.println("DTBS matching: " + result.isDtbsMatching()); +} +``` + +See [Best Practices — Signature Response](/rest-api-guide/best-practices#signature-response) for the full validation checklist. + +## Error Handling + +The client uses structured exceptions to communicate failures: + +```java +import ch.swisscom.mid.client.MIDFlowException; +import ch.swisscom.mid.client.config.ConfigurationException; + +try { + SignatureResponse response = client.requestSyncSignature(request); + // handle success +} catch (MIDFlowException e) { + // Communication or business-level failure + Fault fault = e.getFault(); + StatusCode code = fault.getStatusCode(); + FailureReason reason = fault.getFailureReason(); + String detail = fault.getStatusDetail(); + + switch (code) { + case USER_CANCEL: + // User cancelled on their phone + break; + case EXPIRED_TRANSACTION: + // User didn't respond in time + break; + case PIN_NR_BLOCKED: + // User's Mobile ID PIN is blocked + break; + case UNAUTHORIZED_ACCESS: + // Check TLS certificate and AP ID configuration + break; + default: + // See Status and Fault Codes for the full list + break; + } +} catch (ConfigurationException e) { + // Invalid client configuration (keystore, truststore, etc.) +} +``` + +See [Status and Fault Codes](/rest-api-guide/status-fault-codes) for the complete reference. + +## Per-Request AP Credentials + +If a single client instance serves multiple Application Providers, you can override the AP ID and password per request: + +```java +SignatureRequest request = new SignatureRequest(); +request.setOverrideApId("custom-ap-id"); +request.setOverrideApPassword("custom-ap-password"); +// ... remaining request setup +``` + +These overridden credentials are automatically carried into the tracking object used for async polling. + +## Logging + +The client uses SLF4J with the following logger hierarchy: + +| Logger | Purpose | +|--------|---------| +| `ch.swisscom.mid.client` | General client activity | +| `ch.swisscom.mid.client.config` | Configuration-related activity | +| `ch.swisscom.mid.client.protocol` | Protocol-level communication | +| `ch.swisscom.mid.client.requestResponse` | Request/response messages (large data stripped) | +| `ch.swisscom.mid.client.fullRequestResponse` | Full request/response messages (including Base64 data) | + +::: tip +Set `ch.swisscom.mid.client.requestResponse` to `DEBUG` for development and troubleshooting. Avoid enabling `fullRequestResponse` in production as it logs all certificate and signature data. +::: + +## Command-Line Interface + +The client also ships as a CLI tool for quick testing. Download the full package from the [Releases page](https://github.com/MobileID-Strong-Authentication/mobileid-client-java/releases). + +```bash +# Generate sample configuration files +./bin/mid-client.sh -init + +# Query a user profile +./bin/mid-client.sh -profile-query -msisdn 41791234567 + +# Request a signature (async with receipt) +./bin/mid-client.sh -sign -msisdn=41791234567 -lang=en \ + -dtbs "Bank ACME: Confirm login" -receipt + +# Use verbose logging for debugging +./bin/mid-client.sh -sign -msisdn=41791234567 -lang=en \ + -dtbs "Bank ACME: Confirm login" -vv +``` + +## Further Resources + +- [GitHub Repository](https://github.com/MobileID-Strong-Authentication/mobileid-client-java) — Source code, full documentation, and releases +- [Configuration Guide](https://github.com/MobileID-Strong-Authentication/mobileid-client-java/blob/main/docs/configure-the-client.md) — Detailed configuration reference +- [Proxy Configuration](https://github.com/MobileID-Strong-Authentication/mobileid-client-java/blob/main/docs/configure-proxy-connection.md) — HTTP proxy setup +- [Troubleshooting](/rest-api-guide/troubleshooting) — Common problems and solutions + +--- + +## REST API Troubleshooting + +Source: https://docs.mobileid.ch/rest-api-guide/troubleshooting.html + +# Troubleshooting + +This page covers the most common problems encountered when integrating with the Mobile ID service and how to diagnose them. While some examples reference the [Java Reference Client](/rest-api-guide/java-reference-client), the underlying causes and solutions apply to any client implementation. + +## Diagnosing Connection Problems + +Most initial integration issues are related to the TLS/mTLS connection setup. Understanding the difference between common connection errors helps narrow down the root cause quickly. + +### Connection Timed Out + +**Symptom:** The client waits for a long time and then fails with a "connect timed out" error. + +**Cause:** The Mobile ID endpoint is not reachable from your network. This is typically a firewall or routing issue. + +**Solutions:** +- Verify that your network allows outbound connections to `mobileid.swisscom.com` on the required port. +- Check if a proxy is required in your environment and configure it accordingly. +- Ensure the endpoint URL is correct (see [Integration Steps — Endpoint Address](/rest-api-guide/app-provider-client-integration#endpoint-address)). + +### Connection Refused + +**Symptom:** The client fails immediately with a "connection refused" error. + +**Cause:** The Mobile ID endpoint is reachable at the network level, but your client's source IP address has not been whitelisted in the Swisscom firewall. + +**Solutions:** +- Contact Swisscom to have your public IP address (or range) added to the allowlist. +- If you connect through a proxy or NAT gateway, make sure the **outbound** IP is what gets whitelisted. +- Verify the configured port and endpoint URL. + +::: tip Distinguishing the Two +**Timed out** = no response at all (firewall drop or routing issue). +**Refused** = a response was received rejecting the connection (IP not whitelisted or wrong port). +::: + +## TLS and Certificate Issues + +### Wrong Client Certificate or AP ID (Fault 104) + +**Symptom:** The Mobile ID service returns fault code `_104` with reason `UNAUTHORIZED_ACCESS` and detail `Wrong SSL credentials`. + +```json +{ + "Fault": { + "Code": { + "SubCode": { "Value": "_104" }, + "Value": "Sender" + }, + "Detail": "Wrong SSL credentials", + "Reason": "UNAUTHORIZED_ACCESS" + } +} +``` + +**Possible Causes:** +1. The client certificate used during the TLS handshake is not the one enrolled with Swisscom. +2. The certificate alias configured in the keystore is incorrect (the wrong certificate is being sent). +3. The AP ID does not match the one provisioned for your account. +4. The client is sending the full certificate chain instead of just the end-entity certificate. + +**Solutions:** +- Verify the certificate alias in your keystore configuration matches the enrolled certificate. +- Double-check the AP ID value received from Swisscom. +- Ensure your client sends only the end-entity certificate, not the full chain (see [Mutual Authentication](/rest-api-guide/app-provider-client-integration#mutual-authentication)). + +### Hostname Verification Failure + +**Symptom:** TLS handshake fails with an error like `Certificate for doesn't match any of the subject alternative names`. + +**Cause:** The hostname in the endpoint URL does not match the server certificate's Subject Alternative Names (SANs). This typically means the endpoint URL is incorrect. + +**Solutions:** +- Use the standard endpoint URL `https://mobileid.swisscom.com` (see [Integration Steps — Endpoint Address](/rest-api-guide/app-provider-client-integration#endpoint-address)). +- If connecting via Swisscom EC, ensure hostname verification is configured for the EC endpoint. + +### Server Certificate Not Trusted + +**Symptom:** TLS handshake fails with a "PKIX path building failed" or "unable to find valid certification path" error. + +**Cause:** The Mobile ID server certificate's CA (SwissSign Gold CA — G2) is not in your client's trust store. + +**Solutions:** +- Add the SwissSign Gold CA — G2 root certificate to your trust store (see [Root CA Certificates](/rest-api-guide/root-ca-certs)). +- If using a Java keystore, import it with: + +```bash +keytool -importcert -alias swisssign-gold-g2 \ + -file SwissSign_Gold_CA_-_G2.crt \ + -keystore truststore.jks +``` + +### Keystore or Trust Store Not Found + +**Symptom:** The client fails at startup with a `FileNotFoundException` for the keystore or trust store file. + +**Solutions:** +- Verify the file path is correct (absolute or relative to the application's working directory). +- Ensure the file exists and is readable by the application process. + +### Invalid Keystore or Key Password + +**Symptom:** The client fails with `Keystore was tampered with, or password was incorrect` or `Cannot recover key`. + +**Solutions:** +- Verify the keystore password and the private key password separately — they can differ. +- Use `keytool -list -keystore keystore.jks` to test the keystore password. + +## Request-Level Errors + +### Wrong Parameters (Fault 101) + +The AP's request contains invalid parameter values. Common causes: +- The `Instant` timestamp deviates too much from the server's current time. +- Invalid MSISDN format. + +### Missing Parameters (Fault 102) + +A required field is missing from the request. Verify all mandatory fields are set (see [Mobile ID API](/rest-api-guide/mobile-id-api#mss-signature)). + +### DTBD Too Long (Fault 103) + +The `DataToBeDisplayed` exceeds the maximum allowed length: +- **239 characters** if all characters are in the GSM default alphabet. +- **119 characters** if any character falls outside the GSM set (e.g., `ç`). + +See [Best Practices — Signature Request](/rest-api-guide/best-practices#signature-request) for DTBD guidelines. + +### DTBD Prefix Missing (Fault 107) + +The `DataToBeDisplayed` does not start with the mandatory AP-specific prefix (e.g., `"Bank ACME: "`). This prefix is assigned by Swisscom during provisioning. + +### Unknown Client (Fault 105) + +The MSISDN is not known to the Mobile ID service. The user may not have activated Mobile ID, or the MSISDN format is incorrect. + +### Signature Already in Progress (Fault 406) + +Another signature request is already active for the same MSISDN and authentication method. For the SIM method, wait for the existing transaction to complete. For the App method, the previous transaction is automatically cancelled. + +See [Best Practices — Signature Concurrency Control](/rest-api-guide/best-practices#signature-concurrency-control) for details. + +## Timeout and Polling Issues + +### Response Timeout + +**Symptom:** The client times out waiting for a synchronous signature response. + +**Cause:** The HTTP response timeout is shorter than the signature transaction timeout. For synchronous requests, the server holds the connection open until the user responds or the transaction expires. + +**Recommended timeouts:** + +| Operation | Transaction Timeout | Client Connection Timeout | +|-----------|---------------------|---------------------------| +| Sync Signature (SIM) | 80 seconds | 90 seconds | +| Sync Signature (App) | 40 seconds | 50 seconds | +| Async Signature | 80 / 40 seconds | 10 seconds | +| Status Query | — | 10 seconds | +| Receipt | — | 90 seconds | +| Profile Query | — | 10 seconds | + +### Async Polling Stops Prematurely + +When polling for async signature status, continue polling while the status is `REQUEST_OK` (100) or `OUTSTANDING_TRANSACTION` (504). A final state is reached when you receive either: +- `SIGNATURE` (500) or `VALID_SIGNATURE` (502) — success +- Any fault code — failure + +Use a polling interval of **5 seconds** as a reasonable default. + +## Debugging Tips + +### Enable TLS Debugging + +To diagnose TLS handshake issues, enable JVM-level TLS logging: + +```bash +# Full TLS debug output +java -Djavax.net.debug=all ... + +# More targeted: handshake and certificate info only +java -Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager \ + -Djava.security.debug=certpath ... +``` + +### Enable HTTP Request/Response Logging + +For the [Java Reference Client](/rest-api-guide/java-reference-client#logging), set the appropriate loggers to `DEBUG`: + +```xml + +``` + +### Use Test MSISDNs + +Mobile ID provides dedicated test MSISDNs that return specific fault codes, letting you test your error handling without a real mobile device. + +Pattern: `+41000092` — for example, `+41000092401` returns fault `401 / USER_CANCEL`. + +See [Status and Fault Codes — Testing](/rest-api-guide/status-fault-codes#testing-status-and-fault-codes) for the full list. + +### Use the Java CLI for Quick Testing + +The [Java Reference Client CLI](/rest-api-guide/java-reference-client#command-line-interface) is a convenient way to verify your setup independently of your application code: + +```bash +# Test connectivity and credentials with a profile query +./bin/mid-client.sh -profile-query -msisdn 41791234567 + +# Test with verbose logging +./bin/mid-client.sh -profile-query -msisdn 41791234567 -vv + +# Test with full TLS and HTTP traffic logging +./bin/mid-client.sh -profile-query -msisdn 41791234567 -vvv +``` + +## Common Error Quick Reference + +| Symptom | Likely Cause | See | +|---------|-------------|-----| +| Connection timed out | Firewall / network issue | [Connection Timed Out](#connection-timed-out) | +| Connection refused | IP not whitelisted | [Connection Refused](#connection-refused) | +| Fault 104 — UNAUTHORIZED_ACCESS | Wrong cert or AP ID | [Wrong Client Certificate](#wrong-client-certificate-or-ap-id-fault-104) | +| Fault 101 — WRONG_PARAM | Bad timestamp or MSISDN | [Wrong Parameters](#wrong-parameters-fault-101) | +| Fault 107 — INAPPROPRIATE_DATA | Missing DTBD prefix | [DTBD Prefix Missing](#dtbd-prefix-missing-fault-107) | +| Fault 105 — UNKNOWN_CLIENT | User not activated | [Unknown Client](#unknown-client-fault-105) | +| Fault 208 — EXPIRED_TRANSACTION | User didn't respond | [Response Timeout](#response-timeout) | +| Fault 406 — PB_SIGNATURE_PROCESS | Concurrent signature | [Signature Already in Progress](#signature-already-in-progress-fault-406) | +| PKIX path building failed | Missing CA in trust store | [Server Certificate Not Trusted](#server-certificate-not-trusted) | +| Keystore tampered with | Wrong password | [Invalid Keystore Password](#invalid-keystore-or-key-password) | + +--- + +## OIDC Introduction + +Source: https://docs.mobileid.ch/oidc-integration-guide/introduction.html + +# Introduction + +This document provides Relying Parties (RPs) with technical guidance and best practices for integrating Mobile ID OpenID Provider (MobileID OP) into their applications. + +The MobileID OP can be used for both authorization and authentication. It fully complies with the [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html) specification. + +::: info OpenID Connect +OpenID Connect is a simple identity layer on top of the [OAuth 2.0](https://datatracker.ietf.org/doc/html/rfc6749) protocol. It allows clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner. + +OpenID Connect allows clients of all types, including Web-based, mobile, and JavaScript clients, to request and receive information about authenticated sessions and end-users. The specification suite is extensible, allowing participants to use optional features such as encryption of identity data, discovery of OpenID Providers, and session management, when it makes sense for them. + +See [OpenID Connect FAQ](https://openid.net/connect/faq/) for a set of answers to Frequently Asked Questions. +::: + +The Mobile ID solution protects access to your company data and applications with a comprehensive end-to-end solution for a strong multi-factor authentication (MFA). Please visit [mobileid.ch](https://mobileid.ch) for further information. Do not hesitate to contact us in case of any questions. + + +## Key Concepts & Terminology + +The most basic key concepts are as follows. + +- **End-User** is the entity that wants to assert a particular identity, the Mobile ID User (a human being). +- **User-Agent** is the program (such as a browser) used by the End-User to communicate with the Relying Party and OpenID Connect Provider. +- **Relying Party (RP)** is our customer's web site or client application that wants to verify the End-User's identifier. It outsources its user authentication function to an OpenID Connect Provider. It can request claims (e.g., user information) about that End-User. +- **OpenID Connect Provider (OP)** is an authorization server that offers authentication as a service and provides claims to a Relying Party about the authentication event and the End-User. +- **Scopes** are identifiers used to specify what access privileges are being requested. +- **Claims** are simply key & value pairs that contain information about an End-User, as well as meta-information about the authentication event. Non-standard claims can be specified as custom claims. +- **Access Token** is a credential used to access protected resources directly. Access tokens usually have an expiration date and are short-lived. They must be kept secret, though security considerations are less strict due to their shorter life. +- **ID Token** is an identity token provided by the OpenID Provider to the Relying Party. The identity token contains a number of claims about that End-User and also attributes about the End-User authentication event, in a standard [JWT](https://datatracker.ietf.org/doc/html/rfc7519) format and signed by the OpenID Provider (so it can be verified by the intended recipients). It may optionally be encrypted for confidentiality. +- **Refresh Token** carries the information necessary to get a new access token. Refresh tokens can also expire but are rather long-lived. + +## Authorization Code Grant Flow + +Mobile ID utilizes the **Authorization Code Grant Type** to obtain an access token that allows the application to retrieve user data after authenticating. The Authorization Code Flow, in abstract, follows these steps: + +```mermaid +sequenceDiagram + actor EU as End-User + participant UA as User-Agent
(Browser, App) + participant RP as Relying Party
company.ch + participant AuthZ as Mobile ID (OP)
Authorization Endpoint + participant Tok as Mobile ID (OP)
Token Endpoint + participant UI as Mobile ID (OP)
UserInfo Endpoint + + rect rgb(240, 248, 255) + Note over EU, AuthZ: (A) + EU->>UA: User clicks sign-in button at https://company.ch to request access to protected resource + UA->>RP: + Note right of RP: optional parameters are
login_hint, ui_locales,
dtbd, acr_values + RP->>AuthZ: + AuthZ->>UA: Redirect to https://m.mobileid.ch + end + + rect rgb(240, 255, 240) + Note over EU, AuthZ: (B) + UA->>AuthZ: Authentication request : client_id, redirect_uri, scope + AuthZ->>AuthZ: Validate client + AuthZ->>UA: Return sign-in page of https://m.mobileid.ch + UA->>AuthZ: User starts sign-in at https://m.mobileid.ch + AuthZ->>AuthZ: Start Mobile ID authentication & authorization
incl. account recovery, if needed + AuthZ->>EU: Mobile ID authentication request to confirm sign in to protected resource + Note left of EU: Authenticate with
Mobile ID + EU->>AuthZ: Mobile ID authentication response + AuthZ->>AuthZ: Cache authentication data temporarily + EU->>AuthZ: User grants access to user information (authorization step) + end + + rect rgb(255, 248, 240) + Note over UA, AuthZ: (C) + AuthZ->>UA: Redirect to https://company.ch + authorization-code (short lived) + UA->>RP: Authorization-code + end + + rect rgb(240, 240, 255) + Note over RP, Tok: (D) + RP->>Tok: Request access token and ID token using authorization-code + Tok->>Tok: Validate authorization-code + end + + rect rgb(255, 240, 255) + Note over RP, Tok: (E) + Tok->>RP: access token & ID token returned (short-lived) + end + + rect rgb(255, 255, 240) + Note over RP, UI: (F) Optionally to retrieve extra user info + RP->>UI: request user claims using ID token + UI->>UI: Validate token + UI->>RP: claims returned (phone number, location, etc.) + RP->>RP: Validate extra user info + end + + rect rgb(245, 245, 245) + Note over EU, RP: (G) + RP->>UA: Allow or deny access based on access token and optional user info + UA->>EU: User is signed in + end +``` + +1. An **End-User** requests access to a protected resource of the Relying Party. For example, the End-User clicks on a sign-in button or launches an app. The Relying Party redirects the User-Agent to the Mobile ID Authorization Endpoint at `https://m.mobileid.ch`. +2. The Mobile ID Authorization Server **authenticates** the End-User (using an appropriate Mobile ID authentication method) and establishes whether the End-User grants or denies the Relying Party Client's access request, including access to extra user information that might have been requested in the scope of the authentication request sent by the Relying Party. +3. The Mobile ID Authorization Server **redirects** the User-Agent back to the Relying Party's web site or application using the redirection URI provided earlier in step 1. The redirection URI includes an **Authorization code** that is valid for a few minutes. +4. Relying Party requests an **Access Token** from the Mobile ID Token Endpoint by including the Authorization code received in the previous step. When making the request, the Relying Party authenticates with the Mobile ID server. The client includes the redirection URI used to obtain the authorization code for verification. +5. The Mobile ID server authenticates the client, validates the authorization code, and ensures that the redirection URI received matches the URI used to redirect the client in step 3. On success, the Mobile ID server will return a JSON object with the **ID Token** and an **Access Token**, and an optional **Refresh Token**. +6. **Optional:** Relying Party requests additional, consented user information (claims). The user info endpoint returns previously consented user profile information to the client. A valid access token is required for that. +7. Relying Party grants or denies access to the requested service and the user is logged in. + +## Refresh Token + +Because Access Tokens are always short-lived (see [Tokens](/oidc-integration-guide/getting-started#tokens)), a Relying Party may want to refresh the Access Token using their long-lived Refresh Token. To refresh an Access Token, the Client must always authenticate at the Token Endpoint. The Relying Party should always validate the Refresh Response. + +![refresh-token](/img/refresh-token.png) + +::: warning +A Relying Party must be authorized to use a Refresh Token. +::: + +--- + +## OIDC Getting Started + +Source: https://docs.mobileid.ch/oidc-integration-guide/getting-started.html + +# Getting Started + +Before you can integrate and use Mobile ID OpenID Connect sign-in, the client on-boarding process must have been completed by Swisscom. + +For the technical on-boarding, you will be asked to provide Swisscom with the following information: + +| What | Quick Description | Ref. | +|------|--------------------|------| +| **Client Display Name** | Your client's name, which is displayed by the authorization server.
Example value: `iDemo Online Shop` | | +| **Redirect URI(s)** | Redirection URI(s) to which the response will be sent. Note that TLS (https) is always required and the localhost URI is not allowed.
Example value:
`https://app01.idemo-company.ch/oauth2/authresp`
`https://app02.idemo-company.ch/oauth2/authresp` | [OIDC spec](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) | +| **Default ACR** | Your default ACR. Must be a value that is available for your selected Mobile ID contract.
Example value: `mid_al3_any` | [Section Auth Code Request](/oidc-integration-guide/getting-started#authorization-code-request) | +| **Client Auth Mode** | Your client's authentication method, either basic or post.
Example value: `client_secret_post` | [Section Access Token Request](/oidc-integration-guide/getting-started#access-token-request) | +| **Always Prompt For Consent** | The Mobile ID server default behavior is to skip the consent step, provided such is already recorded for the given end-user and client.
Default: `false` | | +| **MFA Number Matching** | Enable MFA number matching feature for Mobile ID SIM and Mobile ID App authentication.
When a user responds to an MFA notification using Mobile ID SIM or Mobile ID App, they'll be presented with a number on their mobile. They need to select that number in the sign-in prompt to complete the approval.
Default: `false` | [Video](https://youtu.be/4ACfK_kByKY) | +| **LDAP Settings** | Optional. Mobile ID server can connect to an LDAP(S) to validate user credentials and/or retrieve user attributes from the LDAP, such as:
- MFA mobile number attribute
- Mobile ID Serialnumber attribute (required for ACR mid_al4)
- User password attribute | | +| **CNAME Record** | Optional. Mobile ID server can use a custom domain instead of the default m.mobileid.ch. Custom Domains are only relevant if prompt=login is used. We will need your record name (e.g. mobileid.acme.com) that routes the traffic to m.mobileid.ch. | | + +You will get a unique OIDC client identifier and client secret from Swisscom. +If you did not receive your client credentials, it means that your on-boarding process is not finished yet. + +::: tip +Check the state with your commercial contact or via **Backoffice.Security@swisscom.com**. +::: + +## Endpoint URIs + +A default Mobile ID OpenID Provider configuration is published on the OIDC discovery endpoint, which allows a client to discover the OAuth 2.0 and OpenID Connect endpoints, capabilities, supported cryptographic algorithms and features. + +::: info +It is recommended to host a local copy of the discovery document when your application relies on constant availability of this endpoint data. +::: + +| Endpoint | URL | +|-----------|-----| +| Discovery | https://openid.mobileid.ch/.well-known/openid-configuration | + +Additional Endpoint URIs: + +| Endpoint | URL | +|-----------|-----| +| Authorization | https://m.mobileid.ch/oidc/authorize | +| Token | https://openid.mobileid.ch/token | +| User Info | https://openid.mobileid.ch/userinfo | +| Pushed Authorization Requests | https://openid.mobileid.ch/par | + +## Authorization Code Request + +The authorization code can be obtained by performing a simple HTTP GET request towards the Authorization endpoint of the Mobile ID OP. The client secret is not involved yet. + +| Endpoint | URL | +|-----------|-----| +| Authorization | https://m.mobileid.ch/oidc/authorize | + +The Relying Party may trigger the authorization code flow by calling the authorization link (including required request parameters), for example: + +```html +MobileID-sign-in-button +``` + +::: warning +For data privacy reasons, it is highly recommended that the Relying Party does not fill in the HTTP referrer header. Typically, the referrer header is populated with the address of the page where the request originated. The HTML hyperlinks should have the `rel` attribute set to `noreferrer`, as shown in the example above. +::: + +A button could look like this example: + +mobileid-button + +A click on the button will redirect the user to the mobileid.ch domain, where they can complete the authorization code flow. In the example screenshots below, the user enters the phone number, authenticates with the Mobile ID App and consents to the user information (phone number, current location) that was requested by the Relying Party "iDemo App". Finally, the user is redirected back to the Relying Party's domain. + + idemo-app-login + idemo-app-auth + idemo-app-consens + + +The following request query string parameters are supported: + +| Parameter | Value | Remarks | +|-----------|-------|---------| +| `scope` | MUST contain the value `openid` | Optionally, the client may request additional scopes as specified in [Scopes and Claims](/oidc-integration-guide/getting-started#scopes-and-claims) | +| `response_type` | MUST be the value `code` | | +| `client_id` | MUST be your client ID | | +| `redirect_uri` | MUST be (one of) your redirect URI(s) | | +| `state` | MUST be an opaque value | Used to maintain state between the request and the callback | +| `nonce` | MUST be a nonce value | | +| `acr_values` | CAN be set to overwrite the client's default ACR | Authentication Level (AL) required by the client (see [ACR](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr)) | +| `response_mode` | SHALL NOT be used | | +| `display` | SHALL NOT be used | | +| `prompt` | CAN be set to `login` | | +| `max_age` | SHALL NOT be used | | +| `ui_locales` | CAN be set to provide the user's preferred language | Supported values are `en`, `de`, `fr` and `it` | +| `id_token_hint` | SHALL NOT be used | | +| `claims` | SHALL NOT be used | | +| `login_hint` | CAN be set to provide a login hint to the authorization server about the end-user's phone number(s) or LDAP username. Must be in a JSON format. | See [Login Hint Examples](/oidc-integration-guide/getting-started#login-hint-examples) below. | +| `dtbd` | CAN be set to overwrite the default authentication message displayed to the end-user if the authentication method is either Mobile ID SIM or Mobile ID App. | See [DTBD Parameter](/oidc-integration-guide/getting-started#dtbd-parameter) below. | + +#### Login Hint Examples + +Standard login hints: + +```json +{"enableManualInput": true, "hints": [{"msisdn":"+41765XXXXXX"}]} + +{"enableManualInput": true, "hints": [{"msisdn":"+41765XXXXXX", "default":true}]} + +{"enableManualInput": true, "hints": [{"msisdn":"+41765XXXXXX", "sn":"+574XXXXXX"}]} + +{"enableManualInput": true, "hints": [{"msisdn":"+41765YYYYYY"},{"msisdn":"+41765XXXXXX", "default":true}]} +``` + +If an LDAP has been configured for your OIDC client, you can use the following login hints: + +```json +{"useLDAP": true, "hints": [{"userName":"johndoe"}]} + +{"useLDAP": true, "hints": [{"userName":"john.doe@acme.com", "userPassword":"plain-secret", "isHashed": false}]} + +{"useLDAP": true, "hints": [{"userName":"john.doe@acme.com", "userPassword":"hashed-secret", "isHashed": true}]} +``` + +You can use the following login hint in combination with the `prompt=login` parameter: + +```json +{"useLDAP": true} +``` + +If passkeys are enabled for your account, you can include the `keyringId` field in the login hint: + +```json +{"hints": [{"msisdn":"+41765XXXXXX", "keyringId":"MIDPKXXXXXXXXXX"}]} +``` + +::: info +The `sn` parameter is optional and only required for ACR `mid_al4`. The `keyringId` is required for `mid_al4_passkey` and `mid_al4_any` (when passkeys are enabled). See [Passkey Authentication](/oidc-integration-guide/passkey-authentication) for details. +::: + +#### DTBD Parameter + +The `dtbd` message should include these keywords: + +- `#SESSION#` — A unique transaction number. In case MFA Number Matching is enabled, this keyword will be replaced with the matching number. +- `#CLIENT#` — Relying Party Display Name. + +The default authentication message is: + +| Language | Message | +|----------|---------| +| English | Do you want to login to #CLIENT#? Transaction number #SESSION# | +| German | Möchten Sie sich bei #CLIENT# anmelden? Transaktion Nummer #SESSION# | +| French | Voulez-vous vous connecter à #CLIENT# ? Transaction numéro #SESSION# | +| Italian | Vuoi accedere a #CLIENT#? Transazione numero #SESSION# | + +### Scopes and Claims + +Given below is the list of supported scopes that can be requested during the authorization code request. + +| Scope | Claim | Type | Example Value | Description | +|-------|-------|------|---------------|-------------| +| `openid` | `sub` | string | `3246d772d2edb208...` | Subject identifier (unique, pairwise per client) | +| `offline_access` | — | — | — | Requests a refresh token | +| `profile` | `name` | string | `+41791234567` | User's display name | +| `phone` | `phone_number` | string | `+41791234567` | Phone number in E.164 format | +| | `phone_number_verified` | boolean | `true` | Whether the phone number has been verified | +| `mid_location` | `mid_geo_accuracy` | number | `0` | GPS accuracy in meters | +| | `mid_geo_country` | string | `CH` | ISO country code of the device | +| | `mid_geo_device_confidence` | number | `1.0` | Device confidence score | +| | `mid_geo_location_confidence` | number | `1.0` | Location confidence score | +| | `mid_geo_timestamp` | string | `2022-03-17T05:49:03+01:00` | Timestamp of the geolocation measurement | +| `mid_profile` | `mid_profile_recovery_code_status` | boolean | `true` | Whether a recovery code has been set | +| | `mid_profile_serial` | string | `MIDCHEYUD1YE4QB1` | Mobile ID serial number | +| | `mid_pk_keyringid` | string | `MIDPK123A567B90` | Passkey keyring identifier | +| | `mid_profile_sim_status` | string | `active` | SIM card activation status | +| | `mid_profile_sim_pin_status` | string | `active` | SIM PIN status | +| | `mid_profile_sim_mcc` | string | `228` | Mobile Country Code | +| | `mid_profile_sim_mnc` | string | `01` | Mobile Network Code | +| | `mid_profile_sim_network` | string | `Swisscom` | Mobile network operator name | +| | `mid_profile_app_status` | string | `active` | Mobile ID App activation status | +| | `mid_profile_sscds` | string | — | Secure signature creation device descriptor | +| | `mid_profile_alias` | string | `John` | User-defined alias | +| `mid_cms` | `mid_cms_content` | string | — | CMS signed data (Base64-encoded) | +| `mid_esign_basic` | `mid_esign_basic_assurance_level` | string | `basic` | E-signature assurance level | +| | `mid_esign_basic_jurisdictions` | string | `CH` | Applicable jurisdictions | +| | `mid_esign_basic_has_valid_evidence` | boolean | `true` | Whether valid identity evidence exists | +| `mid_passkey` | `mid_pk_keyringid` | string | `MIDPK123A567B90` | Passkey keyring identifier | +| | `mid_pk_binding` | string | `device-bound` \| `syncable` | Whether the passkey is device-bound or synced | +| | `mid_pk_cert_level` | string | `FIPS140-2` \| `CommonCriteria` | Certification level of the authenticator | +| | `mid_pk_created_ts` | number | `1717584000` | Credential creation timestamp (Unix epoch) | +| | `mid_pk_last_used_ts` | number | `1717591234` | Last usage timestamp (Unix epoch) | +| | `mid_pk_aaguid` | string | `2fc0579f-8113-...` | [FIDO MDS](https://fidoalliance.org/metadata/) authenticator identifier | +| | `mid_pk_cred_fingerprint` | string | `pQECAyYgASFY...` | SHA-256 of the credential public key ([COSE](https://datatracker.ietf.org/doc/html/rfc9052)) | +| | `mid_pk_auth_attachment` | string | `platform` \| `cross-platform` | Authenticator attachment modality | +| | `mid_pk_os_family` | string | `iOS` \| `Android` \| `Windows` | OS family of the authenticator platform | + +::: tip +A Relying Party should always respect the user's privacy and keep the requested claims down to the very essential. For example, using scope `openid` only, the user sign-in will be anonymous. Neither the phone number nor any other user information will be passed on to the Relying Party's application. +::: + +Example claim values, retrieved from the UserInfo endpoint: + +```json +{ + "mid_geo_accuracy": 0, + "mid_geo_country": "CH", + "mid_geo_device_confidence": "1.0", + "mid_geo_location_confidence": "1.0", + "mid_geo_timestamp": "2022-03-17T05:49:03.597+01:00", + "mid_profile_recovery_code_status": true, + "mid_profile_serial": "MIDCHEYUD1YE4QB1", + "name": "+41791234567", + "phone_number": "+41791234567", + "phone_number_verified": true, + "sub": "3246d772d2edb20797fe9359cb3d07da6d01df7db2642e14554d241aef1d1d84" +} +``` + +### Authentication Context Class Reference (ACR) + +Below is an overview of all authentication means offered and supported by Mobile ID OP. The ACR can be requested with an authorization request parameter — or, if the request does not contain such parameter, the client's default ACR is selected. + +An ACR can include one or several different authentication methods. The Mobile ID OP will check the user's authentication possibilities and will select an authentication method that complies with the ACR. + + Included + Excluded + Included, if 'Passkeys' feature is enabled for the client account + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
acr_valuesAuthentication MethodAdditional ChecksNIST-AAL3Remarks

SIM

App

OTP

Passkey

CH

KeyRing
mid_al2_anyPasskey-preferred, if passkeys_enabled:true for the client account.
User can select a fallback method if Passkey Auth fails.
Use this AL if UX is more important than security.

Optional login_hint to provide MSISDN:
{"enableManualInput": false, "hints": [{"msisdn":"+41765XXXXXX"}]}
mid_al3_anySee note [1]
mid_al3_any_ch
mid_al3_simcard
mid_al3_mobileapp
mid_al4_anyPasskey-preferred, if passkeys_enabled:true for the client account.
User can select a fallback method if Passkey Auth fails.
Use this AL if security is important and phishing risk is acceptable.

RP must provide SN and KeyRingId (if Passkey is enabled) in login_hint:
{"enableManualInput": false, "hints": [{"msisdn":"+41765XXXXXX", "sn":"+574XXXXXX", "keyringId":"MIDPKXXXXXXXXXX"}]}
mid_al4_any_ch
mid_al4_simcard
mid_al4_mobileapp
mid_al4_passkeyPasskey-only & phishing-resistant.
Use this AL if security and phishing-resistance is important, with a trade-off that only Passkeys can be used.

Optionally, this scenario may be used to comply with NIST AAL3, which requires the user to have a FIPS 140-2 certified authenticator (passkey) registered.

RP must provide KeyRingId in login_hint:
{"hints": [{"msisdn":"+41765XXXXXX", "keyringId":"MIDPKXXXXXXXXXX"}]}
+ +**[1]** Passkeys are only supported with AL2 or AL4. There is no support for Passkeys with AL3. See [Passkey Authentication](/oidc-integration-guide/passkey-authentication) for detailed passkey ACR documentation. + +If a user has more than one authentication method available that comply with the requested ACR, the Mobile ID OP will use the following preference (note, all authentication methods are equally billed): + +| Prio | Condition (User Mobile ID Account Status) | AL "any" choice | +|------|-------------------------------------------|------------------| +| 1 | Active Mobile ID SIM card | Mobile ID SIM | +| 2 | Inactive Mobile ID SIM card & Inactive Mobile ID App | Mobile ID SIM (Account Recovery) | +| 3 | Unknown SIM card & Active Mobile ID App | Mobile ID App | +| 4 | Unknown SIM card & Inactive Mobile ID App | AL2: One-Time-Password SMS
AL3: Mobile ID App (Account Recovery)
AL4: Mobile ID App (Account Recovery) | + +::: warning +If your client attempts to request an ACR that is not available with your current Mobile ID contract, an OIDC error `mid_sec_2020` ("unauthorized acr_values used in request", see [Error Scheme](/oidc-integration-guide/getting-started#error-scheme)) is returned. + +Please check with your commercial contact or via **Backoffice.Security@swisscom.com** if you are interested in ACR values that are listed in the table above but currently not configured for your Mobile ID OIDC account. +::: + + +#### MID SN Check – AL4 Guide + +Using an ACR value of **Authentication Level 4** will provide the highest and most secure authentication level. + +The use of such ACR will require the Relying Party to always provide the Mobile ID's serial number via the `login_hint` authorization request parameter, if there is no LDAP configured. If an LDAP is configured, the Mobile ID server will lookup the user's serial number on the LDAP. The Mobile ID authorization server will compare the serial number with the serial number of the authentication response. + +The authentication will be successful if the serial numbers match. A serial number mismatch will result in an authentication failure. + +An account recovery (e.g., activate Mobile ID App) is supported and will result in a successful authentication if a valid user restore option was available and used during the recovery process. + +::: info +The Relying Party must implement its own Mobile ID user registration process to fetch and store the user's current Mobile ID serial number value. Technically, the best way to retrieve the user's current Mobile ID serial number is by starting an authorization request using authentication level 3 (for example `mid_al3_any`) and scope `mid_profile`, so that the Relying Party will retrieve the claim `mid_profile_serial`. +::: + +### Example Authorization Code Request + +```http +HTTP/1.1 302 Found +Location: https://m.mobileid.ch/oidc/authorize? + response_type=code + &scope=openid%20auth_basic + &client_id=s6BhdRkqt3 + &state=af0ifjsldkj + &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb +``` + +## Authorization Code Response + +The response to the authorize request will be an HTTP redirect that results in an HTTP GET request to the `redirect_uri` that was provided for the authorization code request with the following parameters: + +| Parameter | Value | +|-----------|-------| +| `code` | WILL contain the authorization code | +| `state` | WILL contain the state | +| `iss` | WILL contain the issuer of the authorization code: `https://openid.mobileid.ch` | + +::: warning +The authorization code is by default only valid for **10 seconds** after it has been issued. +::: + +### Example Authorization Code Response + +```http +HTTP/1.1 302 Found +Location: https://client.example.org/cb? + code=SplxlOBeZQQYbYS6WxSbIA + &iss=https%3A%2F%2Fopenid.mobileid.ch + &state=af0ifjsldkj +``` + + +## Access Token Request + +The obtained authorization code ([see here](/oidc-integration-guide/getting-started#authorization-code-response)) can be used to receive an access token. This chapter describes how to format the access token request and which data is returned from the access token endpoint. + +The OpenID Connect RFC states that there are 4 possible client authentication methods (used by clients to authenticate to the Authorization Server when using the Token Endpoint). + +Mobile ID OP supports `client_secret_basic` or `client_secret_post` as client authentication method. + +The access token can be obtained by performing an HTTP POST request towards the Token endpoint of the Mobile ID OP. + +| Endpoint | URL | +|----------|-----| +| Token | https://openid.mobileid.ch/token | + +The following query string parameters need to be embedded in the request: + +| Parameter | Value | +|-----------|-------| +| `grant_type` | MUST be the value `authorization_code` | +| `code` | MUST be the authorization code you received from Mobile ID (see [Authorization Code Response](/oidc-integration-guide/getting-started#authorization-code-response)) | +| `redirect_uri` | MUST be the same redirect URI used in the authorization code request | + +| Headers | Value | +|---------|-------| +| `Authorization` | Client ID and client secret encoded according to the HTTP Basic authentication scheme | +| `Content-Type` | MUST be the value `application/x-www-form-urlencoded` | + +### Example Access Token Request + +In this example, basic authentication is used to authenticate the client to the Mobile ID server. + +```http +POST /token HTTP/1.1 +Host: openid.mobileid.ch +Content-Type: application/x-www-form-urlencoded +Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW +grant_type=authorization_code + &code=SplxlOBeZQQYbYS6WxSbIA + &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb +``` + +## Access Token Response + +After receiving and validating a valid and authorized token request from the client, the Authorization Server returns a successful response that includes: + +- **Access Token** +- **ID Token** + +The response is returned in the `application/json` media type. + +The ID token is a JWT and is created (and thus signed, RS256 by default) by the Authorization Server itself. + +### Authentication Method Reference (AMR) + +Authentication Method Reference (AMR) is an attribute within the OpenID Connect Identity Token. The AMR claim makes statements about the authentication method that was used (including additional factors such as geolocation). + + Included + Excluded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
amr_valuesAuthentication MethodRemarks

SIM

App

OTP

Passkey
mid_app
mid_geoOnly returned when an ACR with the _ch suffix was used (mid_al3_any_ch, mid_al4_any_ch), indicating that geolocation was verified to be in Switzerland (CH).
mid_otp
mid_sim
mid_sms
phrStandard AMR "Phishing-Resistant". Only for ACR mid_al4_passkey.
hwkStandard AMR RFC 8176 "Hardware Key"
+ +::: info +The AMR can be helpful in case the client requests an ACR with an "any" value, such as `mid_al3_any` (see section [ACR](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr)). Since there are multiple authentication methods that comply with such ACR, the client will know from the AMR what authentication method the user actually used for the sign-in. + +**Passkey-specific AMR values:** `phr` (Phishing-Resistant, only for `mid_al4_passkey`) and `hwk` (Hardware Key, [RFC 8176](https://datatracker.ietf.org/doc/html/rfc8176)). The `mid_hwk` AMR has been deprecated in favor of the standard `hwk` value. See [Passkey Authentication](/oidc-integration-guide/passkey-authentication#passkey-amr-values) for details. +::: + +### Example Access Token Response + +```http +HTTP/1.1 200 OK +Content-Type: application/json +{ + "access_token": "eyJraWQiOiJDWHVwIiwidH", + "scope": "phone openid profile mid_location", + "id_token": "eyJraWQiOiJDWHVwIiwiYWxnIj", + "token_type": "Bearer", + "expires_in": 600 +} +``` + +::: tip +The content of the access token is meant for consumption by the `/userinfo` endpoint where the client can give the token to get the user consented claim values. The access token is not meant to convey information to the client or be peeked into by the client, only to the accessed protected resources. +::: + +## User Info Request + +The `/userinfo` endpoint is an OAuth 2.0 protected resource of the Mobile ID server where client applications can retrieve consented claims, or assertions, about the logged in end-user. + +Clients must present a valid access token (of type bearer) to retrieve the UserInfo claims. Only those claims that are scoped by the token will be made available to the client. + +The user info can be obtained by performing an HTTP GET or HTTP POST request towards the User Info endpoint of the Mobile ID server. + +| Endpoint | URL | +|----------|-----| +| User Info | https://openid.mobileid.ch/userinfo | + +The following parameters should be added: + +| Headers | Value | +|---------|-------| +| `Authorization` | MUST contain the Bearer 'Access-Token' | + +### Example User Info Request + +```http +GET /userinfo HTTP/1.1 +Host: openid.mobileid.ch +Authorization: Bearer sa7Aebo6Ookoo0oh +``` + +## Refresh Request + +A request to the Token Endpoint can also use a Refresh Token by using the `grant_type` value `refresh_token`. + +To refresh an Access Token, the Client MUST authenticate to the Token Endpoint using the authentication method registered for its `client_id`. The Client sends the parameters via HTTP POST to the Token Endpoint using Form Serialization. + +| Endpoint | URL | +|----------|-----| +| Token | https://openid.mobileid.ch/token | + +The following query string parameters need to be embedded in the request: + +| Parameter | Value | +|-----------|-------| +| `grant_type` | MUST be the value `refresh_token` | +| `client_secret` | MUST be your client secret | +| `refresh_token` | MUST be your refresh token | +| `scope` | MUST be the scope | + +| Headers | Value | +|---------|-------| +| `Content-Type` | MUST be the value `application/x-www-form-urlencoded` | + +### Example Refresh Request + +```http +POST /token HTTP/1.1 +Host: openid.mobileid.ch +Content-Type: application/x-www-form-urlencoded + +client_id=s6BhdRkqt3 + &client_secret=some_secret12345 + &grant_type=refresh_token + &refresh_token=8xLOxBtZp8 +``` + +## Refresh Response + +Upon successful validation of the Refresh Token, the response body is the Token Response. + +### Example Refresh Response + +```http +HTTP/1.1 200 OK +Content-Type: application/json +Cache-Control: no-store +Pragma: no-cache + +{ + "access_token": "TlBN45jURg", + "token_type": "Bearer", + "refresh_token": "9yNOxJtZa5", + "expires_in": 3600 +} +``` + +## Error Scheme + +The Mobile ID authorization service implements an error code scheme, in which various errors are reported back to the Relying Party (client) together with a human-friendly message, a unique error code and the trace-id of the session. + +All fault responses contain an `errorCode`-field and a `description`-field. The description contains a structure as follows: + +```bash +``` + +Example fault response: + +```json +{ + "errorCode" : "unauthorized_client", + "description" : "mid_sec_2010_A9W1GLUM - Unauthorized scopes used in request" +} +``` + +Description of the structure details: + +| Component | Description | +|-----------|-------------| +| `mid` | Schema prefix for codes that belong to Mobile ID | + + +## Error Code Table + +This table presents all the error codes that are currently implemented. + +| OIDC error | Code | Human-friendly text / Description | +|------------|------|-----------------------------------| +| `invalid_request` | `mid_req_1010` | Invalid acr_values parameter, expected one single value | +| `invalid_request` | `mid_req_1020` | Invalid value received for acr_values | +| `invalid_request` | `mid_req_1030` | Invalid ui_locales parameter, expected one single value | +| `invalid_request` | `mid_req_1040` | Invalid value received for ui_locales | +| `invalid_request` | `mid_req_1050` | Invalid login_hint, empty hits are not allowed | +| `invalid_request` | `mid_req_1060` | Invalid login_hint, AL4 cannot be used with enabled manual MSISDN input | +| `invalid_request` | `mid_req_1070` | Invalid MSISDN value in login_hint | +| `invalid_request` | `mid_req_1080` | Duplicated MSISDN value in login_hint | +| `invalid_request` | `mid_req_1090` | Invalid SN value in login_hint | +| `invalid_request` | `mid_req_1100` | Invalid login_hint JSON content | +| `invalid_scope` | `mid_req_1110` | Invalid scopes in request | +| `invalid_request` | `mid_req_1120` | AL4 requested but login_hint is empty | +| `invalid_request` | `mid_req_1130` | Invalid request, missing query string | +| `invalid_request` | `mid_req_1140` | Invalid keyring ID in `login_hint` | +| `invalid_request` | `mid_req_1150` | Invalid `login_hint`, AL4 passkey requested but keyring ID is empty | +| `invalid_request` | `mid_req_1900` | Invalid client request, check request parameters | +| `unauthorized_client` | `mid_sec_2010` | Unauthorized scopes used in request | +| `unauthorized_client` | `mid_sec_2020` | Unauthorized acr_values used in request | +| `unauthorized_client` | `mid_sec_2030` | Unauthorized parameters used in request | +| `access_denied` | `mid_auth_3010` | Authentication rejected by resource owner or authorization server | +| `access_denied` | `mid_auth_3011` | Authentication rejected by resource owner or authorization server. (1) Number-Matching successful and (2) MID request cancelled by the user | +| `access_denied` | `mid_auth_3012` | Authentication failed as user did not respond. (1) Number-Matching successful and (2) MID requested timed out | +| `access_denied` | `mid_auth_3013` | Authentication failed due to number mismatch. (1) Number-Matching failed and (2) MID request successful | +| `access_denied` | `mid_auth_3014` | Authentication rejected by resource owner or authorization server. (1) Number-Matching failed and (2) MID request cancelled by the user | +| `access_denied` | `mid_auth_3015` | Authentication failed as user did not respond. (1) Number-Matching failed and (2) MID request timed out | +| `access_denied` | `mid_auth_3020` | Claims sharing rejected by resource owner or authorization server | +| `access_denied` | `mid_auth_3025` | Signature CMS data validation failed | +| `access_denied` | `mid_auth_3030` | Mobile ID serial number validation failed | +| `access_denied` | `mid_auth_3040` | Country (geo-location) validation failed | +| `access_denied` | `mid_auth_3050` | MSISDN ownership verification failed | +| `access_denied` | `mid_auth_3060` | Mobile ID account activation failed | +| `access_denied` | `mid_auth_3065` | Mobile ID app account activation not completed in time | +| `access_denied` | `mid_auth_3070` | Mobile ID SIM card required for this authentication | +| `access_denied` | `mid_auth_3080` | No authentication method available | +| `access_denied` | `mid_auth_3090` | Authentication via SMS OTP failed | +| `access_denied` | `mid_auth_3100` | Geo accuracy limit validation failed | +| `access_denied` | `mid_auth_3110` | Geo device confidence score limit validation failed | +| `access_denied` | `mid_auth_3120` | Geo location confidence score limit validation failed | +| `access_denied` | `mid_auth_3125` | Geofencing policy violated for referenced AP ID | +| `access_denied` | `mid_auth_3300` | Authentication failed; user did not respond | +| `access_denied` | `mid_auth_3310` | Authentication failed; user is busy with another authentication | +| `access_denied` | `mid_auth_3320` | Authentication failed; provided LDAP credentials were invalid | +| `access_denied` | `mid_auth_3330` | Authentication failed; mandatory LDAP attribute is missing | +| `access_denied` | `mid_auth_3340` | Authentication failed; LDAP server communication exception | +| `access_denied` | `mid_auth_3350` | Authentication failed; LDAP (OIDC) account is time locked | +| `access_denied` | `mid_auth_3400` | Authentication failed; generic LDAP exception | +| `access_denied` | `mid_auth_3500` | Authentication failed; passkey keyring mismatch | +| `access_denied` | `mid_auth_3900` | Authentication failed for other reasons | +| `invalid_request` | `mid_auth_4000` | Invalid `dtbd` parameter used in request | +| `server_error` | `mid_sys_9900` | Internal server error | + + +## Tokens + +This table provides details on OIDC and OAUTH tokens and how the Relying Party should manage them. + +| Token | Type | TTL | Revocable | Refreshable | Validation | Storable | Usage | +|-------|------|-----|-----------|-------------|------------|----------|-------| +| Access Token | bearer | 60 min | no | yes | yes | no | for calling userinfo | +| Authorization Code | string | 2 min | no | no | no | no | For obtaining the access_token, the id_token and refresh_token | +| ID Token | JWT | 60 min | no | yes | yes | no | Proof of IdP's authentication. Expired ID tokens should never be accepted for processing | +| Refresh Token | bearer | configurable per client | yes | yes | no | yes | for obtaining new valid refresh_token, access_token and id_token | + + + +--- + +## OIDC Best Practices + +Source: https://docs.mobileid.ch/oidc-integration-guide/best-practices.html + +# Best Practices + +## Pushed Auth Request (PAR) + +### Back-channel PAR Submission + +The [Pushed Authorisation Request (PAR)](https://datatracker.ietf.org/doc/html/rfc9126) endpoint gives OAuth 2.0 clients a back-channel to post the parameters of an authorisation request to the Mobile ID server, to obtain an opaque URI handle for them, and then continue with the frontend redirection to the authorisation endpoint as usual. + +::: info +Introducing an extra backend call to submit the authorisation parameters has three benefits: + +- **Frees the authorisation request from any browser URL length limits.** They can become an issue with complex requests, such as RAR. +- **Keeps the parameters confidential** between client and server. Regular requests expose them in the URL query string and hence to the browser, the end-user and logs. +- **Confidential OAuth clients will be authenticated up-front**, and the request parameters will be checked for errors, before sending the end-user to the authorisation endpoint for login and consent. +::: + + +### PAR Request (POST) + +Submits the OAuth 2.0 authorisation request parameters to `/par` to obtain a `request_uri` handle for use at the authorisation endpoint. + +**Header parameters:** +- `Authorization` — Used for HTTP basic authentication of the client. +- `Content-Type` — Must be set to `application/x-www-form-urlencoded`. +- `Issuer` — The issuer URL (optional). +- `Tenant-ID` — The tenant ID (optional). + +**Body:** +- The OAuth 2.0 authorisation request parameters, together with any client authentication parameters. + +**Success:** +- Code: `200` +- Content-Type: `application/json` +- Body: `{object}` The PAR response. + +Example PAR request for a confidential client registered for `client_secret_basic` authentication: + +```http +POST /par HTTP/1.1 +Host: openid.mobileid.ch +Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW +Content-Type: application/x-www-form-urlencoded + +response_type=code +&scope=openid%20email +&client_id=fcb5e4f1 +&state=af0ifjsldkj +&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb +``` + +Example PAR request for a public client with [PKCE](https://datatracker.ietf.org/doc/html/rfc7636): + +```http +POST /par HTTP/1.1 +Host: openid.mobileid.ch +Content-Type: application/x-www-form-urlencoded + +response_type=code +&scope=openid%20email +&client_id=fcb5e4f1 +&state=af0ifjsldkj +&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb +&code_challenge_method=S256 +&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM +``` + +Example response with a request URI to complete the authorisation: + +```http +HTTP/1.1 200 OK +Content-Type: application/json;charset=UTF-8 +Cache-Control: no-store +Pragma: no-cache + +{ + "request_uri" : "urn:ietf:params:oauth:request_uri:OsL1Z3VqIxAT9R77wB7KCw.5-cQUNt9DygE4XxnYjysnw", + "expires_in" : 60 +} +``` + +### PAR Response + +JSON object with members: + +- `request_uri` — The request URI handle to use at the authorisation endpoint. +- `expires_in` — The configured lifetime of the request URI, in seconds. + +Example: + +```json +{ + "request_uri" : "urn:ietf:params:oauth:request_uri:OsL1Z3VqIxAT9R77wB7KCw.5-cQUNt9DygE4XxnYjysnw", + "expires_in" : 60 +} +``` + +## Token and response validation + +According to the OIDC specification, RPs must ensure that the received tokens are valid. The following chapters summarize the Relying Party's obligations when consuming OIDC/OAUTH tokens and responses. + +### Authentication Request + +Provide state and nonce values with sufficient entropy. + +- [OIDC Core — AuthRequest](http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) +- [OIDC Core — NonceNotes](http://openid.net/specs/openid-connect-core-1_0.html#NonceNotes) + +### Validate Auth Responses + +Handle the state parameter correctly. + +- [OIDC Core — AuthResponseValidation](http://openid.net/specs/openid-connect-core-1_0.html#AuthResponseValidation) + +### Validate Token Responses + +Validate the ID Token and verify scopes. + +- [OIDC Core — TokenResponseValidation](http://openid.net/specs/openid-connect-core-1_0.html#TokenResponseValidation) + +### Validate ID token + +Relying Parties must validate ID Tokens. The Mobile ID OP signs ID Tokens with **RS256** by default. To verify the signature, fetch the public key from the JWKS endpoint: + +| Resource | URL | +|----------|-----| +| Discovery | https://openid.mobileid.ch/.well-known/openid-configuration | +| JWKS | https://openid.mobileid.ch/jwks.json | + +**Practical validation steps:** + +1. Decode the JWT header and extract the `kid` (Key ID). +2. Fetch the matching public key from the [JWKS endpoint](https://openid.mobileid.ch/jwks.json) (cache the key set and refresh when an unknown `kid` appears). +3. Verify the RS256 signature using the public key. +4. Validate the standard claims: + - `iss` must equal `https://openid.mobileid.ch` + - `aud` must contain your `client_id` + - `exp` must not be in the past + - `nonce` must match the value you sent in the authorization request + +::: tip +Most OIDC client libraries (e.g. `openid-client` for Node.js, `authlib` for Python, Spring Security for Java) handle JWKS fetching and ID Token validation automatically when configured with the discovery URL. It is strongly recommended to rely on a well-maintained library rather than implementing token validation manually. +::: + +- [OIDC Core — IDTokenValidation](http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation) + +### Protect Client ID and secret + +::: warning +Relying Party's credentials (for example, client secret) must be stored safely to remain a secret only known by the Relying Party. Relying Party should inform the Mobile ID OP in case credentials have been compromised. +::: + +### Store tokens securely + +::: warning +Tokens, especially Refresh Tokens, must be treated as credentials and stored securely in a place where only the End-Users for whom they were issued can access them. +::: + +## Test Users + +There are test user accounts available for testing and debugging purposes. + +::: info +Due to the strict phone number validation during the Mobile ID authorization flow, these test phone numbers will only be accepted by the Mobile ID server if they are provided via the `login_hint` request parameter. Your account must be authorized to use the `login_hint` parameter and requires the use of Pushed Authorisation Requests (PAR), which keeps the parameters confidential between client and server (see section [Pushed Authorization Request (PAR)](/oidc-integration-guide/best-practices#pushed-authorization-request-par)). +::: + +| MSISDN | Auth | Description | +|--------|------|-------------| +| `+41-700092501` | SIM | Robot User (EC key; Swisscom Root CA 2 Certificate) | +| `+41-700092502` | SIM | Robot User (RSA key; Swisscom Root CA 2 Certificate) | +| `+41-000092401` | SIM | Simulated user to test the Mobile ID Error 401; USER_CANCEL | +| `+41-000092402` | SIM | Simulated user to test the Mobile ID Error 402; PIN_BLOCKED | +| `+41-000092403` | SIM | Simulated user to test the Mobile ID Error 403; CARD_BLOCKED | +| `+41-000092404` | SIM | Simulated user to test the Mobile ID Error 404; NO_KEY_FOUND | +| `+41-000092406` | SIM | Simulated user to test the Mobile ID Error 406; PB_SIGNATURE_PROCESS | + +--- + +## OIDC Passkey Authentication + +Source: https://docs.mobileid.ch/oidc-integration-guide/passkey-authentication.html + +# Passkey Authentication (early access) + +::: warning Early Access +MobileID Passkeys are now live in the production environment as a **freshly launched capability**. We still describe the feature as early access because the rollout is recent and platform compatibility, policy options, and operational guidance may continue to evolve quickly. Check back shortly for updates. +::: + +MobileID now supports **FIDO2 Passkeys** as an authentication method within the OpenID Connect service. Relying Parties can allow their users to authenticate using MobileID Passkeys - alongside or instead of the existing MobileID SIM, App, and OTP SMS methods. + +## What Are Passkeys? + +The MobileID ecosystem already offers several proven authentication methods: **MobileID SIM** (SIM-based authentication), **MobileID App** (push-based authentication on iOS and Android), and **OTP SMS**. With the introduction of **FIDO2 Passkeys**, MobileID now adds a modern, phishing-resistant authentication option to its portfolio - giving Relying Parties and their users even more flexibility to balance security and convenience. + +Passkeys are built on the [FIDO2](https://fidoalliance.org/fido2/) standard and the [WebAuthn](https://www.w3.org/TR/webauthn-2/) API. Instead of passwords, passkeys use **public-key cryptography**: a private key stays securely on the user's device (or synced within a platform ecosystem), while the corresponding public key is stored by the service. + +Key characteristics of passkeys: + +- **Phishing-resistant** - Authentication is cryptographically bound to the origin (domain), so credentials cannot be phished or replayed on a different site. +- **Passwordless** - Users authenticate with biometrics (fingerprint, face), a device PIN, or a hardware security key. No passwords to remember or leak. +- **Multi-factor by design** - Passkeys inherently combine possession (the device holding the private key) with a user verification factor (biometrics or PIN), satisfying multi-factor authentication requirements in a single gesture. +- **Multi-device** - Depending on the passkey type, credentials can be synced across devices within a platform ecosystem (e.g., Apple iCloud Keychain, Google Password Manager) or bound to a single hardware device (e.g., YubiKey). + +### Device-Bound vs. Synced Passkeys + +The term "Passkeys" is an **umbrella term** for FIDO2-based authenticators. Under the hood, these can be **platform authenticators** (built into a device, such as Touch ID or Windows Hello) or **roaming authenticators** (external hardware keys, such as a YubiKey). These authenticator types differ significantly in how they store the private key - and this distinction directly impacts the security assurance level they can achieve. + +For MobileID, one of the most relevant security standards is [**NIST AAL3**](https://pages.nist.gov/800-63-3/sp800-63b.html) (Authentication Assurance Level 3), which specifies the highest level of authentication assurance. To achieve AAL3, the authenticator must be **device-bound** (the private key cannot be exported or synced) and the hardware must be **[FIPS 140-2](https://csrc.nist.gov/pubs/fips/140-2/upd2/final) certified**. Cloud-synced passkeys - while phishing-resistant and suitable for AAL2 - do not meet AAL3 because the private key is exportable across devices. + +This distinction matters for Relying Parties integrating MobileID: while **MobileID users are free to register any type of passkey** in their [MyMobileID Dashboard](https://mobileid.ch/login), the **RP has full control** over which passkey types are accepted during authentication. Through the passkey claims returned by MobileID (see [Passkey Scope and Claims](#passkey-scope-and-claims)), the RP can enforce specific requirements - for example, accepting only FIPS 140-2 certified, device-bound passkeys for high-assurance use cases. + +| Aspect | Device-Bound Passkeys | Cloud-Synced Passkeys | +|--------|----------------------|----------------------| +| **Private key storage** | Stored locally on a single device's secure hardware (e.g., Secure Enclave, [TPM](https://trustedcomputinggroup.org/resource/tpm-library-specification/)) | Synced across devices via encrypted cloud services (e.g., iCloud Keychain, Google Password Manager) | +| **Examples** | YubiKey, Windows Hello, hardware security keys | Apple Passkeys, Google Passkeys | +| **Portability** | Tied to one device; if lost, the passkey is lost | Available on all devices within the user's ecosystem | +| **NIST AAL3 compliance** | Yes (if FIPS 140-2 certified) | No (private key is exportable) | +| **Phishing-resistant** | Yes | Yes | + +::: info +Only **device-bound passkeys** on **FIPS 140-2 certified** authenticators (e.g., YubiKey 5 FIPS Series with firmware 5.7+) can meet [NIST AAL3](https://pages.nist.gov/800-63-3/sp800-63b.html) requirements. Cloud-synced passkeys are phishing-resistant and meet AAL2, but do not satisfy AAL3 because the private key can be exported. +::: + +### Platform and Browser Compatibility + +FIDO2/WebAuthn support is **not uniform** across operating systems, browsers, and transport methods (USB, NFC, Bluetooth). Whether a given passkey works in a particular environment depends on the combination of the operating system, browser, authenticator type, and whether user verification (PIN or biometrics) is required. These factors can lead to situations where a passkey that works on one platform fails on another. + +::: warning Known limitation: Hardware security keys over NFC on Android +At the time of writing, **Android does not support PIN-protected FIDO2 credentials over NFC**. Only USB transport is supported for credentials that require user verification via PIN. This means that **FIPS-compliant hardware security keys** that enforce a PIN (such as the YubiKey 5 FIPS Series) **cannot be used via NFC on Android devices**, although they work as expected over USB. The same keys work fine over both NFC and USB on **iOS/iPadOS** and **desktop platforms**. + +This is a platform-level restriction, not a MobileID limitation. The current status may change as Android and Google Play Services evolve. +::: + +The passkey ecosystem is evolving rapidly. Rather than providing version-specific compatibility details here (which would quickly become outdated), Relying Parties and their users should consult the following **actively maintained resources** for the latest platform and browser support status: + +- [**passkeys.dev: Device Support**](https://passkeys.dev/device-support/) - FIDO Alliance community-maintained device and browser support matrix. +- [**Yubico: WebAuthn Browser Support**](https://developers.yubico.com/WebAuthn/WebAuthn_Browser_Support/) - Detailed compatibility tables for hardware security keys, including transport method support (USB, NFC, Lightning) per platform. +- [**Token2: FIDO2 OS and Browser Compatibility**](https://www.token2.com/site/page/understanding-fido2-authentication-across-different-operating-systems-and-browsers) - Broader overview of FIDO2 support across operating systems and browsers, including known limitations. +- [**Can I Use: Web Authentication API**](https://caniuse.com/webauthn) - Browser-level WebAuthn API support overview. + +::: tip Recommendation for Relying Parties +To accommodate users on platforms with incomplete passkey support, prefer **fallback ACR values** (`mid_al2_any` or `mid_al4_any`) over passkey-only ACRs. This ensures users can always complete authentication, falling back to MobileID SIM, App, or OTP SMS, even when their device or browser does not support their passkey's transport method. See [Passkey-Only vs. Fallback](#passkey-only-vs-fallback) for details. +::: + +## Why MobileID Passkeys? + +Implementing passkey registration, management, and authentication from scratch is **complex and resource-intensive** for Relying Parties. MobileID Passkeys remove this burden entirely by leveraging a concept familiar from established OpenID Connect providers: **all passkey operations happen on the `mobileid.ch` domain**. + +Similar to how signing in with Google redirects the user to `google.com` for authentication, MobileID redirects the user to `mobileid.ch` during the OIDC authorization code flow. Because the user's passkeys are **bound to the `mobileid.ch` origin**, they work seamlessly across any Relying Party that integrates MobileID - the user registers their passkeys once and can authenticate at any RP, regardless of the RP's domain. This centralized approach maintains full security guarantees, including the ability to achieve the highest assurance levels such as **NIST AAL3** (see [Authentication Flow](#authentication-flow-oidc) below). + +By using MobileID Passkeys, RPs benefit from: + +- **No passkey infrastructure to build** - MobileID handles the entire FIDO2/WebAuthn registration and authentication lifecycle. RPs integrate via the standard OpenID Connect protocol they already use. +- **Centralized passkey management** - Users register and manage their passkeys on the [MyMobileID Dashboard](https://mobileid.ch/login), secured by MobileID step-up authentication. RPs do not need to build passkey management UIs. +- **Single registration, multi-RP usage** - Passkeys are bound to the `mobileid.ch` domain, not to individual RP domains. A single MobileID Passkey works across all Relying Parties that use MobileID OIDC. +- **Flexible authenticator support** - Users can register passkeys from different platforms and vendors (Apple, Google, YubiKey, Windows Hello, etc.) and manage multiple passkeys on their account. +- **NIST AAL3 possible** - With FIPS 140-2 certified authenticators, RPs can achieve the highest NIST assurance level through MobileID, without building any of the complex infrastructure themselves. +- **Backward-compatible** - If an RP ignores all passkey-related parameters, or if passkeys are not enabled for the client account, the runtime behavior is identical to the current release. + +## How It Works + +### Passkey Registration + +Users register their passkeys on the **MyMobileID Dashboard** at [https://mobileid.ch/login](https://mobileid.ch/login): + +1. The user authenticates to the MyMobileID Dashboard (via SMS OTP verification). +2. In the dashboard, the user selects **Manage Passkeys**. +3. The user registers one or more passkeys - the passkey name defaults to their MobileID mobile number. +4. Passkeys are bound to the `mobileid.ch` domain, enabling cross-RP usage. + +Users can register passkeys from different platforms (e.g., Apple Touch ID, Google Password Manager, YubiKey) and manage (list/delete) them at any time. + +
+ Passkey management tile on the MyMobileID Dashboard +
Passkey management tile
+
+
+ List of registered passkeys on the MyMobileID Dashboard +
Registered passkeys with KeyRingID and metadata
+
+ +### Authentication Flow (OIDC) + +During the OpenID Connect authorization code flow, passkey authentication works as follows: + +1. The user clicks the login button on the **Relying Party's** website. +2. The user's browser is **redirected** from the RP's domain to the `mobileid.ch` domain (the MobileID OpenID Provider). +3. On the `mobileid.ch` domain, the user is prompted to authenticate with their **MobileID Passkey** - this works because the passkeys were registered on the same `mobileid.ch` domain. +4. After successful passkey authentication, the user is redirected back to the RP with the authorization code. +5. The RP completes the standard token exchange and retrieves user claims. + +::: tip +The passkey authentication is **usernameless** and **passwordless** - the user simply confirms with biometrics, a PIN, or by tapping their hardware key. No phone number or username entry is needed if the RP enforces passkey-only authentication. +::: + +### Passkey-Only vs. Fallback + +Depending on the chosen ACR value, the RP can configure two modes: + +- **Passkey-only** (e.g., `mid_al4_passkey`): Only passkey authentication is allowed. If the user cannot authenticate with a passkey, they must abort and register a new passkey on the MyMobileID Dashboard before trying again. +- **Passkey-preferred with fallback** (e.g., `mid_al2_any`, `mid_al4_any` with passkeys enabled): Passkey authentication is tried first. If it fails, the user can fall back to MobileID SIM, App, or OTP SMS. + +
+ Passkey-only authentication flow +
Passkey-only
+
+
+ Passkey-preferred with fallback methods +
Passkey-preferred with fallback
+
+ +### RP Control Over Passkey Quality + +Beyond choosing between passkey-only and fallback modes, the RP can **enforce specific passkey quality requirements**. Every passkey authentication returns detailed claims via the `mid_passkey` scope (see [Passkey Scope and Claims](#passkey-scope-and-claims)), such as `mid_pk_cert_level` (e.g., `FIPS140-2`), `mid_pk_binding` (e.g., `device-bound`), and `mid_pk_aaguid` (authenticator model). The RP can evaluate these claims to accept or reject the authentication based on its own security policy. + +The highest assurance level is achieved with the ACR value **`mid_al4_passkey`**, which requires the RP to provide a `keyringId` in the `login_hint`. This enables **KeyRingID matching** - a MobileID-specific mechanism that guarantees **NIST AAL3** compliance: + +- The **KeyRingID** is a stable identifier associated with the user's passkey registration. As long as the KeyRingID matches, MobileID guarantees that the user is authenticating with a passkey that was registered through a verified step-up authentication process, ensuring continuity of trust. +- If the KeyRingID **no longer matches**, it means the user has changed their passkey (e.g., registered a new one) but the required step-up authentication during the registration on the MyMobileID Portal was skipped or bypassed. In this case, AAL3 cannot be guaranteed, and the RP is notified via the claims. +- The KeyRingID is returned as the `mid_pk_keyringid` claim and should be stored by the RP for subsequent authentication requests at AL4. + +This gives the RP a spectrum of choices - from using passkeys purely as a **UX improvement** (e.g., `mid_al2_any` with fallback to SIM/App), to enforcing the **highest security level** (e.g., `mid_al4_passkey` with KeyRingID and FIPS 140-2 validation). The various ACR values and their properties are detailed in the [Passkey ACR Values](#passkey-acr-values) table. + +## OIDC Passkey Parameters + +### Core Request Parameters + +The following table shows the request parameters for an authorization request that uses passkey authentication. Most parameters are the same as for standard MobileID OIDC requests (see [Getting Started](/oidc-integration-guide/getting-started#authorization-code-request)). + +| Parameter | Required | Example | Notes | +|-----------|----------|---------|-------| +| `response_type` | Yes | `code` | Standard OIDC | +| `scope` | Yes | `openid phone mid_passkey` | Add `mid_passkey` for passkey claims | +| `client_id` | Yes | `rpdemo` | Issued by Swisscom | +| `redirect_uri` | Yes | `https://rp.example.com/cb` | Must match registration | +| `acr_values` | Yes | `mid_al4_passkey` | See [Passkey ACR Values](#passkey-acr-values) | +| `state` / `nonce` | Yes | random | Standard OIDC | +| `ui_locales` | No | `de` | `en`, `de`, `fr`, `it` | +| `login_hint` | No | JSON | See [Login Hint Extensions](#login-hint-extensions) | +| `dtbd` | No | `"Login to #CLIENT#?"` | Ignored for passkey authentication | + +::: warning +The `dtbd` parameter is **ignored** during passkey authentication, since the FIDO2 authentication ceremony is handled natively by the browser/authenticator. +::: + +### Passkey Scope and Claims + +To receive passkey-related claims, add the `mid_passkey` scope to the authorization request. The following claims are returned via the **UserInfo endpoint** (or optionally in the ID Token): + +| Scope | Claim | Type | Example Value | Description | +|-------|-------|------|---------------|-------------| +| `mid_passkey` | `mid_pk_keyringid` | string | `MIDPK123A567B90` | The user's passkey keyring identifier | +| | `mid_pk_binding` | string | `device-bound` \| `syncable` | Whether the passkey is bound to a device or synced | +| | `mid_pk_cert_level` | string | `FIPS140-2` \| `CommonCriteria` | Certification level of the authenticator | +| | `mid_pk_created_ts` | number | `1717584000` | When the credential was first registered (Unix epoch) | +| | `mid_pk_last_used_ts` | number | `1717591234` | Last usage timestamp (helps risk engines spot dormant keys) | +| | `mid_pk_aaguid` | string | `2fc0579f-8113-...` | [FIDO Metadata Service](https://fidoalliance.org/metadata/) identifier; maps to authenticator vendor/model | +| | `mid_pk_cred_fingerprint` | string | `pQECAyYgASFY...` | SHA-256 of the credential public key ([COSE](https://datatracker.ietf.org/doc/html/rfc9052) format) | +| | `mid_pk_auth_attachment` | string | `platform` \| `cross-platform` | Authenticator attachment modality | +| | `mid_pk_os_family` | string | `iOS` \| `Android` \| `Windows` | OS family of the authenticator platform | + +::: tip Claim delivery and availability +The `mid_pk_keyringid` claim is also available via the `mid_profile` scope, allowing RPs to retrieve the KeyRingID without requesting the full `mid_passkey` scope. + +**ID Token** should carry the minimal set of claims needed for cryptographic proof (sub, iss, aud, acr, amr, nonce, etc.). **UserInfo endpoint** is the recommended delivery channel for passkey detail claims, as they may change and can be verbose. + +Following OIDC best practice, if a specific claim is not available for a given authentication (e.g., the authenticator does not report a certification level), that claim is simply **omitted from the response** rather than returned with a null or empty value. +::: + +### Login Hint Extensions + +The `login_hint` JSON schema has been extended with passkey-related fields. The full schema is: + +```json +{ + "enableManualInput": true, + "useLDAP": false, + "hints": [ + { + "msisdn": "+41791234567", + "sn": "MIDCHEYUD1YE4QB1", + "keyringId": "MIDPK123A567B90", + "userName": "john.doe", + "userPassword": "plain-secret", + "isHashed": false, + "default": true + } + ] +} +``` + +New passkey-specific field: + +| Field | Type | Description | +|-------|------|-------------| +| `keyringId` | string | Restricts passkey authentication to a specific keyring. **Required** for `mid_al4_passkey` and `mid_al4_any` (when passkeys are enabled). | + +Rules: + +- Omit fields you don't need - the server tolerates missing keys. +- `sn` must be present for AL4 unless fetched via LDAP. +- `keyringId` is required for AL4 passkey flows to enforce a specific keyring. +- `useLDAP` and `msisdn` are mutually exclusive. + +#### Passkey Login Hint Examples + +Passkey-only (AL4): + +```json +{"hints": [{"msisdn": "+41765XXXXXX", "keyringId": "MIDPKXXXXXXXXXX"}]} +``` + +Passkey-preferred with SIM/App fallback (AL4): + +```json +{"enableManualInput": false, "hints": [{"msisdn": "+41765XXXXXX", "sn": "+574XXXXXX", "keyringId": "MIDPKXXXXXXXXXX"}]} +``` + +Passkey-preferred (AL2), no keyring restriction: + +```json +{"enableManualInput": true, "hints": [{"msisdn": "+41765XXXXXX"}]} +``` + +### Passkey ACR Values + +The following table shows how passkeys fit into the MobileID Authentication Level (AL) matrix. Passkeys are supported at **AL2** and **AL4**. There is no passkey support at AL3. + + Included + Excluded + Included, if 'Passkeys' feature is enabled for the client account + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
acr_valuesAuthentication MethodAdditional ChecksNIST-AAL3Remarks

SIM

App

OTP

Passkey

CH

KeyRing
mid_al2_anyPasskey-preferred, if passkeys_enabled:true for the client account.
User can select a fallback method if Passkey Auth fails.
Use this AL if UX is more important than security.

Optional login_hint to provide MSISDN:
{"enableManualInput": false, "hints": [{"msisdn":"+41765XXXXXX"}]}
mid_al3_anySee note [1]
mid_al3_any_ch
mid_al3_simcard
mid_al3_mobileapp
mid_al4_anyPasskey-preferred, if passkeys_enabled:true for the client account.
User can select a fallback method if Passkey Auth fails.
Use this AL if security is important and phishing risk is acceptable.

RP must provide SN and KeyRingId (if Passkey is enabled) in login_hint:
{"enableManualInput": false, "hints": [{"msisdn":"+41765XXXXXX", "sn":"+574XXXXXX", "keyringId":"MIDPKXXXXXXXXXX"}]}
mid_al4_any_ch
mid_al4_simcard
mid_al4_mobileapp
mid_al4_passkeyPasskey-only & phishing-resistant.
Use this AL if security and phishing-resistance is important, with a trade-off that only Passkeys can be used.

Optionally, this scenario may be used to comply with NIST AAL3, which requires the user to have a FIPS 140-2 certified authenticator (passkey) registered.

RP must provide KeyRingId in login_hint:
{"hints": [{"msisdn":"+41765XXXXXX", "keyringId":"MIDPKXXXXXXXXXX"}]}
+ +**[1]** Passkeys are only supported with AL2 or AL4. There is no support for Passkeys with AL3. To keep things simple, the RP should use AL4 and provide `keyringId` via `login_hint`. + +### Passkey Feature Flag + +Passkey support is controlled via the `passkeys_enabled` flag, which Swisscom configures **per OIDC client** (a single RP can have multiple OIDC clients). The RP can request Swisscom to set this flag to `true` or `false` for each of its clients. + +This flag determines whether passkeys are available and affects the authentication method priority order when the RP requests an ACR with `_any` suffix: + +| `passkeys_enabled` (per client) | Priority order for `_any` ACRs | +|-------------------------------|----------------| +| `false` (default) | SIM :arrow_right: App :arrow_right: SMS | +| `true` | Passkey :arrow_right: SIM :arrow_right: App :arrow_right: SMS | + +When set to `true` and the user has a registered passkey, passkey authentication is offered first. If the passkey authentication fails or the user opts out, MobileID falls back to the next available method according to the priority order. + +::: warning +- If the requested ACR is disabled for the client, MobileID returns error `mid_sec_2020`. +- If `passkeys_enabled` is `false` but the RP requests a passkey-only ACR (e.g., `mid_al4_passkey`), MobileID returns `mid_auth_3080` ("No authentication method available"). +::: + +### Passkey AMR Values + +The following AMR (Authentication Method Reference) values are returned in the ID Token when passkey authentication is used: + + Included + Excluded + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
amr_valuesAuthentication MethodRemarks

SIM

App

OTP

Passkey
mid_app
mid_geo
mid_otp
mid_sim
mid_sms
phrStandard AMR "Phishing-Resistant". Only for ACR mid_al4_passkey.
hwkStandard AMR RFC 8176 "Hardware Key"
+ +## Canonical RP Scenarios + +The following table summarizes the most common passkey integration scenarios: + +| # | Goal | `acr_values` | Key `login_hint` flags | Notes | +|---|------|-------------|----------------------|-------| +| 1 | **AL4, Passkey-only, phishing-resistant, FIPS- or device-bound** | `mid_al4_passkey` | `keyringId` | Requires `passkeys_enabled:true`. MobileID restricts passkey choices to the keyring. RP must request scope `mid_passkey` and validate claims to ensure a FIPS- or device-bound passkey was used. | +| 2 | **AL4, Passkey-only, phishing-resistant** | `mid_al4_passkey` | `keyringId` | Requires `passkeys_enabled:true`. MobileID restricts passkey choices to the keyring. | +| 3 | **AL4, Passkey-preferred, SIM/App fallback** | `mid_al4_any` | `keyringId`, `sn`, optional: `enableManualInput`, `msisdn` | MobileID restricts passkey choices to the keyring. `enableManualInput` and `msisdn` may be used for fallback. | +| 4 | **AL2, Passkey-preferred, SIM/App or OTP-SMS fallback** | `mid_al2_any` | optional: `enableManualInput`, `msisdn` | Lightweight passkey integration with full fallback support. | + +::: tip Future improvement +RPs may provide passkey requirements via `login_hint` (e.g., "device-bound") and MobileID could use this to restrict passkey choices to a specific subset of the user's available passkeys. +::: + +## Passkey Error Codes + +In addition to the existing [error codes](/oidc-integration-guide/getting-started#error-code-table), the following errors are specific to passkey authentication: + +| OIDC Error | Code | Description | RP Action | +|------------|------|-------------|-----------| +| `invalid_request` | `mid_req_1140` | Invalid keyring ID in `login_hint` | Provide the keyring ID in the correct format. | +| `invalid_request` | `mid_req_1150` | AL4 passkey requested but keyring ID is empty in `login_hint` | Add valid keyring ID in `login_hint`. | +| `access_denied` | `mid_auth_3500` | Passkey keyring mismatch | Instruct user to use a valid passkey matching the keyring ID. | +| `access_denied` | `mid_auth_3900` | Authentication failed for other reasons (may include passkey validation failure) | Check if passkey validation failed; allow retry. | + +## Backward Compatibility + +MobileID Passkey support is fully backward-compatible: + +- If an RP **ignores all passkey-related parameters** or the client account has `passkeys_enabled:false` (the default), the runtime behavior is **identical to the current release**. +- The `passkeys_enabled` feature flag is managed per `client_id` on the MobileID server. Contact Swisscom to enable passkeys for your account. +- Existing scopes, ACR values, and login_hint formats continue to work unchanged. + +## Enabling Passkeys + +To enable MobileID Passkeys for your OIDC client: + +1. Contact your Swisscom commercial contact or reach out to **Backoffice.Security@swisscom.com**. +2. Update your authorization requests to include passkey-related parameters as documented above. + +::: tip +Start with `mid_al2_any` (passkey-preferred with fallback) for the smoothest user experience, then consider moving to `mid_al4_passkey` (passkey-only) once your users have registered their passkeys. +::: + + + +--- + +## OIDC Public Cloud Integration + +Source: https://docs.mobileid.ch/oidc-integration-guide/cloud-integration-guide.html + +# Public Cloud Integration + +This chapter covers a few Mobile ID integration scenario examples with popular public cloud services. + +## Microsoft Entra ID + +[MobileID](https://www.swisscom.ch/mid) integrates with Microsoft Entra ID using External MFA, enabling Multi-Factor-Authentication (MFA) for Entra ID logon. MobileID provides seamless inline user enrolment, self-service device management, and supports a range of authentication methods, including highly secure crypto-SIM tokens and app-based push authentication for iOS and Android, with advanced options such as Number Matching and Geofencing. + +In 2020, Microsoft announced plans to replace custom controls with a new method for integrating third-party authentication. MobileID has been working closely with Microsoft to deliver an authentication solution for Microsoft External MFA, previously known as External Authentication Methods (EAM), available from May 2024 and generally available since March 2026. + +MobileID via External MFA is fully recognized as a multifactor authentication method within Entra ID, meeting MFA policy requirements. Once MobileID is defined as an External MFA provider, you can create Entra ID conditional access policies with MFA using MobileID and assign these to specific users, groups, or applications. + +::: info +External MFA in Microsoft Entra ID is now generally available. For the current Microsoft guidance, see the [GA announcement](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/external-mfa-in-microsoft-entra-id-is-now-generally-available/4488926), [How to manage external MFA in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-external-method-manage), and the [Microsoft Entra External MFA method provider reference](https://learn.microsoft.com/en-us/entra/identity/authentication/concept-authentication-external-method-provider). External MFA replaces Custom Controls, which Microsoft plans to deprecate on September 30, 2026. +::: + +### Sign-in Flow + +![entraid-sign-in-flow](/img/entraid-sign-in-flow.png) + +### Known Limitations + +- Users must specifically select the MobileID External MFA option during authentication. If they have other MFA methods configured besides MobileID, they may need to click "Other options" on the Microsoft "Verify your identity" prompt in order to choose MobileID. +- Cross-tenant user authentication with MobileID External MFA has limitations. It will only work if: + - The external Microsoft Entra organization trusts MFA claims from the user's home tenant. + - The user has already established a valid MFA claim by authenticating to an application within their home tenant before accessing the cross-tenant application. +- Azure Government does not yet support Entra ID External MFA. Be sure to review Microsoft Entra feature availability for Azure Government. The "Microsoft Entra ID: External Authentication Methods" application is not accessible under MobileID Federal plans. + +### Prerequisites + +To use MobileID MFA with Microsoft Entra ID, you'll need the following: + +- Before you can integrate and use MobileID External MFA, the client onboarding process must have been completed by Swisscom. You will need the following information from Swisscom to be able to create an External MFA method: + - An **Application ID** is generally a multitenant application from your provider, which is used as part of the integration. You need to provide admin consent for this application in your tenant. + - A **Client ID** is an identifier from your provider used as part of the authentication integration to identify Microsoft Entra ID requesting authentication. + - A **Discovery URL** is the OpenID Connect (OIDC) discovery endpoint for the external authentication provider. + +::: tip +If you did not receive this information, it means that your onboarding process is not finished yet. Please check the state with your commercial contact or via **Backoffice.Security@swisscom.com**. +::: + +- An active [Entra ID P1 or P2](https://azure.microsoft.com/en-us/pricing/details/active-directory/) subscription with Conditional Access enabled, and P1/P2 licenses assigned to each user who will log in using MobileID MFA. Plans like Microsoft 365 E3, E5, and F3, as well as Enterprise Mobility + Security E3 and E5, and Microsoft Business Premium, all include Entra ID Premium. +- A designated Entra ID admin account. Configuring the external MFA method and Conditional Access policies requires at least the **Authentication Policy Administrator** role. Granting admin consent for the MobileID application (Step 8 below) requires at least the **Privileged Role Administrator** role. A Global Administrator can perform both steps, but is not the minimum required role for either. You can reduce the account's role privileges after setup is complete. + +### Configure Entra ID + +Follow these steps to configure MobileID as an External MFA method in Microsoft Entra ID: + +| Step | Description | +|------|-------------| +| 1 | **Log in to Entra ID**

Go to the [Microsoft Entra admin center](https://entra.microsoft.com) and log in to your Entra ID tenant as at least an Authentication Policy Administrator. For Step 8 (admin consent), you will need at least the Privileged Role Administrator role.

If you're using the [Azure portal](https://portal.azure.com), the navigation will differ slightly. | +| 2 | **Navigate to Authentication Methods**

In the Entra Admin Center, go to **Entra ID → Authentication methods → Add external MFA**.

If you're logged into the Azure portal instead, first select Microsoft Entra ID, then go to **Security → Authentication Methods**. | +| 3 | **Add External MFA**

Click **+ Add External MFA**.

![entraid-add-external-method](/img/entraid-add-external-method.png) | +| 4 | **Configure the External MFA Method**

On the "Add external MFA" page, enter a descriptive name for the MobileID method. The default name might be "Mobile ID" but you can choose a name that will make sense to your users since they'll see this during authentication.

**Note:** You cannot change the name after creation.

Enter the information you have received from Swisscom in the corresponding field: **Client ID**, **Discovery Endpoint**, **App ID**.

![entraid-configure-external-method](/img/entraid-configure-external-method.png) | +| 5 | **Enable the Method**

If you want to enable MobileID MFA right away, toggle Enable from "Off" to "On". | +| 6 | **Specify Users**

Before saving the new MobileID external method, decide which users should have access to it.

By default, it will apply to all users, meaning any Entra ID user with a Conditional Access Policy requiring multifactor authentication (MFA) will see MobileID as an option.

To apply it to specific users, click **+ Add Target** under the "Include" tab and choose **Select Targets**. On the "Add directory members" page, select one or more Entra ID directory groups that contain the users you want to target for MobileID authentication, then click **Select**. | +| 7 | **Save the Configuration**

After entering all the required details, click **Save** to create the new MobileID external method. | +| 8 | **Grant Admin Consent**

If the "Request admin consent" information shows a **Request permission** button instead of saying "Admin consent granted", click the Request permission button to authorize the MobileID Authentication Method application, making sure to check the box next to **Consent on behalf of your organization** before clicking **Accept**.

entraid-grant-admin-consent

You can verify the permissions if you go to **Identity → Applications → Enterprise applications** and select the MobileID Application, then select **Permissions**. The list of permissions that have been granted for your organization should be shown and it should look similar to this example below:

![entraid-admin-consent-permissions](/img/entraid-admin-consent-permissions.png) | + +### Create and Apply a Conditional Access Policy + +| Step | Description | +|------|-------------| +| 1 | **Log in to Entra ID**

Go to the [Microsoft Entra admin center](https://entra.microsoft.com) and log in to your Entra ID tenant as at least an Authentication Policy Administrator.

If you're using the [Azure portal](https://portal.azure.com), the navigation will differ slightly. | +| 2 | **Navigate to Conditional Access**

Click on **Conditional Access** in the left-hand menu, then click **+ Create New Policy**.

If you are in the Azure portal, navigate to **Security → Conditional Access → Policies**.

![entraid-conditional-access](/img/entraid-conditional-access.png) | +| 3 | **Name the Policy**

Enter a descriptive name for the new policy, such as "MobileID MFA for Acme Users". | +| 4 | **Assign the Policy**

You can assign this policy to specific users or groups, Entra ID cloud apps, or other conditions like client platforms or networks.

*Example for assigning to users:* Click **Users** under "Assignments", then select **Users and groups** on the "Include" tab. Choose **Users and groups** and click **0 users and groups selected** to locate the users or Entra ID security groups for whom you want to enforce MobileID MFA. Select the users or groups, then click **Select** to apply your choices.

If you targeted specific groups when creating the MobileID external method, ensure that you apply this new policy to the same groups.

*Example for assigning to resources:* Click **Target resources**. On the "Include" tab, select **Apps**, and choose the Entra ID applications where you want MobileID MFA to be applied. | +| 5 | **Configure Access Controls**

Click **Grant** under "Access controls", select **Grant access**, and check the box for **Require multifactor authentication**. Click **Select** when done.

![entraid-access-controls](/img/entraid-access-controls.png) | +| 6 | **Enable the Policy**

The final step is to enable the new MobileID conditional access policy. Click the "On" toggle switch under "Enable policy", then click **Create**. The policy will be created and applied to your selected groups or users, enforcing MFA via MobileID. | + +::: warning +Avoid assigning the MobileID policy to all users or all cloud apps at the start, especially for tenant administrators, to prevent potential admin lockouts. Always test the policy with selected users first. Additionally, ensure you create a fail-safe Entra ID administrator account that is excluded from MobileID MFA policies to maintain uninterrupted access. Secure this account with a strong password and a different access condition, such as one based on a trusted network. +::: + +### Additional Configuration to Prioritize MobileID MFA + +If you want users to exclusively use MobileID instead of the Microsoft Authenticator app, follow these steps: + +| Step | Description | +|------|-------------| +| 1 | **Disable the Microsoft Authenticator Registration Campaign**

In the Entra ID admin center, go to **Protection → Authentication Methods → Registration Campaign**.

Click **Edit**, change the State to **Disabled**, and click **Save**.

Alternatively, you can leave the registration campaign enabled and exclude the groups of users who are covered by the MobileID conditional access policy. | +| 2 | **Disable System Preferred MFA for Microsoft Authenticator**

Go to **Protection → Authentication Methods → Settings → System Preferred Multifactor Authentication**.

Click **Edit**, change the State to **Disabled**, and click **Save**. | +| 3 | **Turn Off Microsoft Authenticator**

Navigate to **Protection → Policies**, click **Microsoft Authenticator**.

On the "Enable and Target" tab, toggle the Enable switch to **Off** and click **Save**. | + +### Test Your Setup + +Log in to Entra ID using a user account that has been assigned the Conditional Access policy requiring MFA and is a target for the newly created MobileID external method. + +If you applied the MobileID Conditional Access policy to "All cloud apps", when you log into the Office portal (e.g., [https://office.com](https://office.com)) and submit your primary Entra ID credentials, you'll see your MobileID External MFA method as an option for identity verification. The name displayed will be the one you entered when setting up the MobileID External MFA method in Entra ID. + +entraid-verify-identity + +Choose the "Mobile ID" method to begin MobileID MFA authentication. + +If you have multiple Entra ID authentication methods enabled, you may need to click "Other options" to view and select the MobileID method. + +entraid-other-options + +You will be redirected to the MobileID prompt or user enrolment, depending on your configuration. + +Once you complete the MobileID authentication, you'll return to Entra ID to finish logging in to the application. + +entraid-authentication-complete + +If your Conditional Access policy requiring MFA is only applied to specific applications, the initial login to the Office portal will not prompt for MobileID MFA. However, accessing the protected application within the Office portal or directly will trigger the MobileID MFA prompt. + +::: warning +If you encounter the "Looks like something went wrong" error from Microsoft, the new External MFA settings might need additional time to propagate. If the error persists, you may request support from Swisscom. +::: + +### Troubleshooting + +Need some help? Please ask your commercial contact or get in touch with **Backoffice.Security@swisscom.com** to ask for support. + +## Microsoft Azure AD B2C + +Azure Active Directory B2C is a Single-Sign-On (SSO) solution for any API, web, or mobile application. It enables any organization to provide their users with access using identities they already have, such as Mobile ID. + +::: info +Mobile ID is officially supported by Microsoft Azure and the setup is described on their [official article](https://learn.microsoft.com/en-us/azure/active-directory-b2c/identity-provider-generic-openid-connect). +::: + +Microsoft will act as the secure front door to any of these applications and they will worry about the safety and scalability of the authentication platform. Azure will handle things like denial of service or brute force attacks, so that organizations can focus on their core business and stay out of the identity business. + +## Amazon Cognito + +Amazon Cognito lets you add user sign-up, sign-in, and access control to your web and mobile apps quickly and easily. Amazon Cognito scales to millions of users and supports sign-in with social identity providers, such as Apple, Facebook, Google, and Amazon, and enterprise identity providers via SAML 2.0 and OpenID Connect. + +::: tip +This [article](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-oidc-idp.html) explains how to integrate user sign-in with an OpenID Connect IdP such as Mobile ID. +::: + +amazon-cognito-config + +--- + +## OIDC Use Cases + +Source: https://docs.mobileid.ch/oidc-integration-guide/oidc-use-cases.html + +# MobileID OIDC - Use Cases + +This chapter provides additional guidelines about the various parameter settings in the authorization request. + +## Prompt user for MSISDN + +If the request does not contain a `login_hint` nor `prompt` parameter, the result will be that the user must enter the phone number on the MobileID side, as shown in the figure below. This is a typical **B2C** scenario, for example the MobileID login to a public web shop. + +::: info +The Relying Party won't know the user's MSISDN unless the user gives their consent. +::: + +![use-case-msisdn-prompt-user](/img/use-case-msisdn-prompt-user.png) + +## RP knows the MSISDN + +If the request contains a `login_hint` parameter with the user's phone number, the MobileID authentication can start immediately. + +![use-case-msisdn-rp-knows](/img/use-case-msisdn-rp-knows.png) + + +## Prompt for User Credentials + +If the request contains a `login_hint` parameter set to `useLDAP:true` and a `prompt` parameter set to `login`, the result will be that the user must enter the user credentials on the MobileID side, as shown in the figure below. This is a typical **B2B** scenario, for example the MobileID login to a company service. + +MobileID service will look up the username on the Active Directory (LDAP), verify the user password and retrieve the user's mobile phone number, before it will eventually start the MobileID authentication. + +::: tip +Instead of the MobileID domain (`m.mobileid.ch`), we can configure your custom domain instead. +::: + +![use-case-rp-knows-username](/img/use-case-rp-knows-username.png) + +## RP knows the username + +If the request contains a `login_hint` parameter set to `useLDAP:true` but there is no `prompt` parameter, the result will be that the MobileID service will look up the username on the Active Directory (LDAP) to retrieve the user's mobile phone number, before it will eventually start the MobileID authentication. + +![use-case-prompt-user-credentials](/img/use-case-prompt-user-credentials.png) + +--- + +## OIDC Message Formats + +Source: https://docs.mobileid.ch/oidc-integration-guide/message-formats.html + +# Message Formats on the Mobile ID App + +Mobile ID App screens can present the Data-To-Be-Displayed (DTBD) in two formats. + +::: tip +Use **Classic DTBD** for short confirmations and when you must support SIM users. Keep messages concise and always include the "DTBD Prefix". + +Use **Transaction Approval** when readability matters (e.g., [PSD2](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=celex%3A32015L2366) payments, contract consent, step up login verification). Force the App method with Device LoA4, keep within byte limits, and generate the escaped JSON programmatically. +::: + +1. **Classic DTBD** (single text line) uses a plain UTF-8 string that is also signed (DTBS). + + Supported by SIM and App methods. + + Length limited and no formatting options. + + message-formats-classic + + +2. **Transaction Approval** (key/value pairs) is a structured App-only format that renders a title (type) and one or more key and value rows for improved readability. + + Approve/Cancel becomes active only after the user scrolls to the end if content exceeds one screen. + + RPs request this by sending a JSON object in the dtbd authorization parameter. + + message-formats-transaction-approval + + +## Classic DTBD + +A single UTF-8 string shown on the device. The classic DTBD must include the AP-specific DTBD prefix (e.g., `Bank ACME:`) and is supported by both SIM and App methods. + +::: warning +Keep the DTBD short. Maximum **239 characters**; if any character falls outside the [GSM 03.38](https://en.wikipedia.org/wiki/GSM_03.38) set, effective maximum is **119 characters**. +::: + +Parameter: `dtbd` with a plain string. The OP renders the classic one-line message. + +Typical request excerpt: + +```bash +...&dtbd=Please%20confirm%20your%20login%20to%20MyBank%20eBanking +``` + + +## Transaction Approval + +A structured DTBD that the Mobile ID App renders as a title and rows of key/value pairs. If content overflows, the user must scroll to the bottom; only then are Approve/Cancel enabled. + +::: warning +SIM does not support this format. Always select an App ACR (e.g., `mid_al3_mobileapp`). +::: + +How to request it: Send a JSON object via the `dtbd` authorization request parameter; the value must be URL-encoded (percent-encoding). If the decoded value starts with `{` and validates against the schema/limits below and the user has an active App, the OP renders the key/value screen. + +```json +{ + "type": "", + "dtbd": [ + { "key": "", "value": "" } + /* up to 20 pairs */ + ] +} +``` + +**Limits** (in bytes): + +- `type` ≤ 100 +- ≤ 20 pairs +- each `key` ≤ 100, each `value` ≤ 2000 +- sum(keys+values) ≤ 2000 (bytes; non-ASCII uses 2–4 bytes) +- **DTBD Prefix** (required): your configured prefix must be in the value of the first pair + e.g., `{"key":"Company","value":"Acme AG: ..."}` + +## Transaction Approval Example + +### Pretty JSON + +Build this first. + +```json +{ + "type": "Address Change Confirmation", + "dtbd": [ + { "key": "Company", "value": "Acme AG" }, + { "key": "Full Name", "value": "Philipp Haupt" }, + { "key": "Old Address", "value": "Bahnhofstrasse 1, 8001 Zürich" }, + { "key": "New Address", "value": "Sihlquai 55, 8005 Zürich" }, + { "key": "Effective Date", "value": "01 June 2025" }, + { "key": "Consent Instruction", "value": "Reply APPROVE to consent or CANCEL" } + ] +} +``` + +### Single-line + +What you URL-encode as `dtbd=` + +```json +{"type":"Address Change Confirmation","dtbd":[{"key":"Company","value":"Acme AG"},{"key":"Full Name","value":"Philipp Haupt"},{"key":"Old Address","value":"Bahnhofstrasse 1, 8001 Zürich"},{"key":"New Address","value":"Sihlquai 55, 8005 Zürich"},{"key":"Effective Date","value":"01 June 2025"},{"key":"Consent Instruction","value":"Reply APPROVE to consent or CANCEL"}]} +``` + +Below is another example that includes the keywords `#CLIENT#` and `#SESSION#`, as described in section [DTBD Parameter](/oidc-integration-guide/getting-started#dtbd-parameter). + +```bash +{"type":"LOGIN","dtbd":[{"key":"Company","value":"#CLIENT#"},{"key":"Session","value":"#SESSION#"}]} +``` + +### Authorization request (excerpt) + +::: tip +Use PAR to avoid URL length limits and keep parameters confidential. +::: + +Or pass `dtbd` directly on the authorize URL: + +```http +GET /oidc/authorize? + response_type=code + &scope=openid + &client_id=YOUR_CLIENT_ID + &state=... + &redirect_uri=https%3A%2F%2Fclient.example%2Fcb + &acr_values=mid_al3_mobileapp + &dtbd=%7B%22type%22%3A%22Address%20Change%20Confirmation%22%2C%22dtbd%22%3A%5B%7B%22key%22%3A%22Company%22%2C%22value%22%3A%22Acme%20AG%22%7D%2C...%5D%7D +``` + +::: warning +Request an App ACR (e.g., `mid_al3_mobileapp`) if you want to ensure the App method is selected. +::: + +## Signed Data Comparison + +**Classic DTBD:** the service signs the visible text string. + +**Transaction Approval:** the App signs a normalized JSON object of the form: + +```json +{"format_version":1,"content_string":"[{\"key\":\"Company\",\"value\":\"Test\"}]"} +``` + +i.e., the `dtbd` array only; the `type` label is not part of the signed bytes. + +## Best practices + +::: info +- **Build → URL-encode → send:** generate the JSON with your library, then URL-encode as `dtbd`. Avoid hand-crafted strings. (Use PAR for large payloads/confidentiality.) +- **Select App method:** use `acr_values` (e.g., `mid_al3_mobileapp`) when you want to ensure App UX. +- **Prefix rule:** include your DTBD prefix in the value of the first pair. +- **Respect byte limits:** limits are in bytes, not characters; UTF-8 non-ASCII uses 2–4 bytes. +- **Number-matching & keywords:** `#SESSION#` and `#CLIENT#` keywords are supported in `type`, `key`, or `value` and can be used to implement number matching. +::: + +--- + +## RADIUS Introduction + +Source: https://docs.mobileid.ch/radius-interface-gateway-guide/introduction.html + +# Introduction + +The RIG (RADIUS Interface Gateway) application is an API Gateway for Mobile ID, exposing a RADIUS interface towards the clients and using the Mobile ID API at `mobileid.swisscom.com` for translating the requests of the RADIUS clients into requests for the Mobile ID service. + +The Mobile ID solution protects access to your company data and applications with a comprehensive end-to-end solution for strong multi-factor authentication (MFA). Please visit [mobileid.ch](https://mobileid.ch) for further information. Do not hesitate to contact us in case of any questions. + +The RIG application is the ideal solution in a setup where an existing RADIUS-based network transitions from single-factor authentication (User-Name + User-Password) or two-factor authentication (User-Name + User-Password plus a security device challenge) to Multi-Factor Authentication, by customizing the authentication flow of a RADIUS session and introducing a new step that uses Mobile ID strong authentication. + +During authentication via RADIUS, an extra step requires users to confirm the access to the service on their mobile phones. + +Some clients might decide to move from 1FA (one-factor authentication) to 2FA: username + password and Mobile ID. Other clients might decide to stick with 2FA but replace the existing combination of username + password and security device challenge with username + password plus Mobile ID as additional MFA. + +RADIUS users are typically defined in the format `user@domain`. However, Mobile ID requires the phone number (MSISDN) of the user. Therefore, the phone number of the target user should be provided with one of the following options: + +- RIG connects to a customer's **Directory Service (LDAP)** to retrieve user attributes such as phone number (MSISDN) or other optional attributes such as User-Language, MobileID serial number, or the user's preferred authentication method. +- The RADIUS client provides the **MSISDN as part of the User-Name** (e.g. `4179xxxxxxx@mydomain.com`). + +## RIG Feature List + +### Features Available + +- **Multitenancy** — configure one or multiple customers, each with their own AP_ID, RADIUS shared secret, LDAP settings, and MFA preferences +- **Cloud-native microservice architecture** — horizontal scalability with Redis-based cluster synchronization +- **Single-node deployment** — run without Redis for SIM/APP-only setups (no OTP); ideal for smaller deployments and proof-of-concept environments +- **Authentication methods** — Mobile ID SIM digital signature, Mobile ID App digital signature, OTP via Text SMS +- **Automatic authentication fallback** with configurable method priority per customer +- **MFA method selection via LDAP** — per-user method assignment via LDAP attribute or group membership (`memberOf`) +- **MFA method "None"** — temporarily disable MFA per user or group +- **Geofencing** — whitelist/blacklist country configuration, LDAP group-based geofencing, configurable device and location confidence scores +- **LDAP(S) integration** — retrieve `userPassword`, `mobile`, `preferredLanguage`, serial number, and preferred MFA method; supports primary/secondary/tertiary host failover +- **LDAP search scope and referral** configuration +- **Flexible LDAP search filters** with `{username}`, `{domain}`, and `{userdn}` placeholders +- **LDAP authentication without admin/service user** — authenticate using the client's own credentials +- **User Account Control** attribute support (Active Directory) +- **Mobile ID serial number validation** — optionally validate the user's Mobile ID serial number against an LDAP attribute +- **RADIUS Accounting** with optional webhook forwarding to external systems +- **RADIUS Class attribute** in Access-Accept responses, mapped from LDAP group membership +- **Custom RADIUS Reply Messages** for Access-Reject packets, with I18N support (German, French, Italian, English) +- **Custom Text SMS notifications** for specific error events (e.g., serial number mismatch, geofencing errors) +- **SMS notifications for inactive Mobile ID users** — notify users to activate their Mobile ID account after a fallback authentication +- **Fortinet Vendor Specific Attributes (VSA)** — map LDAP groups to Fortinet group names and access profiles +- **Duplicate packet handling** — configurable deduplication to prevent redundant authentication sessions +- **Docker secrets support** via `_FILE` environment variables +- **Health check endpoint** — HTTP `/health` endpoint for container orchestration +- [**BlastRADIUS**](https://www.blastradius.fail/) **mitigation** — Message-Authenticator support ([CVE-2024-3596](https://nvd.nist.gov/vuln/detail/CVE-2024-3596)) + +### Features Planned + +- RADIUS Dynamic Fields: Allow RADIUS clients to provide custom MSISDN, DTBD, and Auth-Method +- Advanced RADIUS encryption (EAP-TLS, EAP-TTLS, PEAP, EAP-MD5, LEAP) +- RADIUS Proxy Mode (forward Access-Request after successful MFA to another third-party RADIUS server) + +## Service Architecture + +The RADIUS Interface Gateway (RIG) service is developed as a cloud-native microservice application. As is the norm with this type of application, RIG is both vertically and horizontally scalable. For the latter capability, the service is designed to work well in a cluster setup, with multiple RIG nodes synchronizing between them and serving client requests. This helps with load balancing and ensures high availability in production. + +The following diagram shows a cluster setup for RIG: + +RIG cluster setup + +Since nodes need a way of communicating between them and considering the specific target runtime environment, a good approach for this inter-node synchronization is via a common **Redis database cluster**. Each node connects to this database and is able to save and read data from all the other nodes in a RIG cluster. An ongoing authentication session, for example, will have its data stored by node A in the Redis database, with node B later reading the data for that session and carrying it on. + +Requests coming from outside of the RIG cluster reach a proxy service and are then dispatched to one appropriate RIG node. It is up to the proxy to select the right node, but any policy will work fine, as all RIG nodes have the same quality and level of data access, so any one of them could handle a request at any time. Of course, the proxy is responsible for carefully distributing the load on available nodes, but from the point of view of the RIG nodes, the functionality is the same, regardless of the chosen node. + +### Single-Node Deployment (without Redis) + +For smaller deployments or proof-of-concept setups, RIG can be deployed as a single container instance without a Redis database. In this mode, session state is stored in-memory. This is suitable when: + +- Only **SIM** and/or **APP** authentication methods are used (no OTP) +- High availability and horizontal scaling are not required + +This deployment mode significantly reduces infrastructure requirements — only a single RIG container is needed. See the [Deployment](/radius-interface-gateway-guide/deployment) page for configuration details. + +Moving one level down in the architectural view, the following diagram shows the main logical parts of the RIG service: + +RIG internal architecture + +## Authentication Methods + +One of the main components of the RIG service is responsible for managing the authentication methods that are available for a client and selecting the right method on a per-user basis. + +The following authentication methods are currently supported: + +- **SIM Digital Signature** — The user is prompted to confirm a transaction (RADIUS authentication session) and create a digital signature using his/her Mobile ID-enabled SIM chip. +- **App Digital Signature** — Like the SIM method above, but the signing "device" is a mobile application with its keys protected by the phone's system protection. +- **OTP over Text SMS** — An OTP code is generated for each authentication session and sent to the user via an SMS message. A RADIUS Access-Challenge + Access-Request round trip is used to challenge the user to enter the OTP received via SMS. + +For each RADIUS client configured for the RIG service, the following parameters need to be specified: + +- The **available authentication methods** +- The **default method**, in case all other methods are unavailable + +During an authentication session, the RIG service loads this configuration and tries to match it to the current state of the user's Mobile ID account. + +Each customer account can have its custom list of allowed MFA methods with its own order of priority. An LDAP user attribute may be used to set a preferred MFA option per user (if the configuration parameter `UseUserMfaMethod` is set to `true`). This will always override any other configured order of priority. + +If a preferred MFA option (from an LDAP user attribute) is not active or not allowed by the customer configuration, the system falls back to the next MFA option according to the configured order of priority. + +--- + +## RADIUS RIG Deployment + +Source: https://docs.mobileid.ch/radius-interface-gateway-guide/deployment.html + +# RIG Deployment + +There are different types of container services you may use to deploy and run microservices like the RIG application in a high-availability setup. + +We generally recommend using **Kubernetes** or similar container orchestration options to have a platform that automates the tasks related to the management, deployment, and scaling of container clusters. + +RIG container deployment + +Docker images and Helm charts may be used. The latter one facilitates the packaging and deployment of more complex setups in target Kubernetes environments. This works if the customer is already operating a Docker/Swarm environment or a Kubernetes one. + +If simpler setups are needed, the RIG service and dependent components can be delivered and installed as standard software applications. + +## Preconditions + +The following points must be considered before you proceed with the deployment. + +### General Requirements + +- A Mobile ID contract exists. You know your `AP_ID` and your API key (PFX/PKCS#12 format). +- A Directory Service (LDAP) exists, which contains user attributes such as name and phone number. +- An appropriate security concept exists (e.g. secured network communication, hardening, etc.). + +### NAS Requirements + +- The NAS RADIUS Access-Request packet contains either a **unique NAS-Identifier attribute** or it has a **unique and static source IP address/range**. RIG will pick the configuration based on this info. +- The RADIUS client timeout shall be set to **60 seconds**. This ensures enough time for the user to respond to the Mobile ID authentication request. +- The RADIUS client retry shall be set to no more than **1**. The client should not retry because there might still be a Mobile ID authentication session ongoing. + +### Connectivity Requirements + +Connectivity must be allowed as follows: + +- **RADIUS** (UDP/1812) — Requests from your NAS (e.g. VPN server) to the RIG application (or the UDP network load balancer that forwards the requests to the RIG application nodes). +- **LDAPS** (TCP/636) — From the RIG application to your LDAP server. +- **HTTPS** (TCP/443) — From the RIG application to the Mobile ID API endpoint at `mobileid.swisscom.com` (Internet) or `195.65.233.218` ([EC](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html)). +- **REDIS** (TCP/6379) — Between the RIG application nodes and the Redis database cluster. +- **HTTP** (TCP/80) — Local connectivity for the Docker health check (optional). + +You can verify the LDAP connectivity using the following command on the node where the RIG container application is running. You may also use `ldaps` (port 636) instead of `ldap` (port 389): + +```bash +ldapwhoami -x -w -D "cn=,ou=,dc=,dc=" -H ldap://:389 +``` + +When troubleshooting LDAP configuration issues, you can use `ldapsearch` to query user attributes directly: + +```bash +ldapsearch -LLL -H ldap://:389 \ + -b "ou=,dc=,dc=" \ + -D "cn=,dc=,dc=" \ + -w \ + -s sub "(&(objectclass=inetOrgPerson)(uid=))" +``` + +You can verify the Mobile ID API connectivity using the following command on the node where the RIG container application is running: + +```bash +openssl s_client -connect mobileid.swisscom.com:443 +``` + +Note: The firewall on the Mobile ID API side has an IP-based whitelist. Therefore, the source IP address/range of the request sent to the Mobile ID API must be in the whitelist. If the IP address is unknown, the packet will be dropped and your request will time out. + +## Configuration + +RIG supports two configuration sources for customer settings and I18N error messages: + +- **KeyValueStorage (Redis)** — Customer configurations and I18N messages are stored as JSON in Redis. This is the recommended approach for production and multi-node deployments, as configurations can be updated at runtime. +- **AppSettings (Environment Variables)** — All configuration is provided via environment variables. This is suitable for single-node deployments without Redis. + +For detailed configuration options including customer setup, LDAP integration, geofencing, Fortinet VSA, MFA method mapping, SMS notifications, and I18N error messages, see the [Configuration](/radius-interface-gateway-guide/configuration) page. + +## Docker Run + +You can pull the Docker images from [Docker Hub](https://hub.docker.com/repository/docker/mobileidch/mid-radius-rig) or from [Amazon ECR](https://gallery.ecr.aws/mobileidch/mid-radius-rig). + +For high availability, you will need the following components, running at least two instances each: + +- **Mobile ID RADIUS Interface Gateway application** — [Docker Hub](https://hub.docker.com/repository/docker/mobileidch/mid-radius-rig) or [Amazon ECR](https://gallery.ecr.aws/mobileidch/mid-radius-rig) +- **Redis database** using `redis` (requires 3 nodes for HA; alternatively, `keydb` may be used) +- **Redis web management tool** using `redis-commander` to manage the Redis database content +- **UDP network load balancer** using `nginx` with a custom `nginx.conf` configuration + +How to pull an image from Docker Hub: + +```bash +docker pull mobileidch/mid-radius-rig +``` + +How to pull an image from Amazon ECR: + +```bash +docker pull public.ecr.aws/mobileidch/mid-radius-rig +``` + +How to run a Docker application: + +```bash +docker run -d -p 1812:1812/udp --env-file mobileidch/mid-radius-rig +``` + +### Environment File + +Below is an example `.env` file for a clustered RIG setup with Redis. Change the example according to your preferences. + +At least the following parameters must be updated: + +- **`MID_CLIENT_CERTIFICATE`** — Your base64-encoded Mobile ID API key (PFX/PKCS#12, without password). + + ```bash + base64 -w 0 + ``` + +- **`Schnittstellen__MobileIdClient__Host`** — The Mobile ID API endpoint: `https://mobileid.swisscom.com` (Internet) or `https://195.65.233.218` ([Enterprise Connect](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html)). + +- **`Schnittstellen__KeyValueStorage__ConnectionString`** — Your Redis connection string. + +```bash +# Application Configuration +ASPNETCORE_ENVIRONMENT=Production + +# Base64-encoded MobileID Client Key (PFX/P12, PKCS#12, without password) +MID_CLIENT_CERTIFICATE=MIIJW*** + +# Serilog Log Configuration +# Valid levels: Verbose -> Debug -> Information -> Warning -> Error -> Fatal +Serilog__MinimumLevel__Default=Information +Serilog__MinimumLevel__Override__Microsoft=Warning +Serilog__MinimumLevel__Override__Microsoft.Hosting.Lifetime=Warning +Serilog__MinimumLevel__Override__Microsoft.Extensions.Diagnostics.HealthChecks=Error +Serilog__MinimumLevel__Override__Flexinets.Radius.RadiusServer=Information +Serilog__MinimumLevel__Override__Flexinets.Radius.Core=Information +Serilog__WriteTo__0__Args__outputTemplate={Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u4} [{CorrelationId}] {SourceContext} - {Message:lj}{NewLine}{Exception} + +# WebServer Port (used for health check endpoint) +WebServer__Port=80 + +# RADIUS Server Configuration +RadiusServer__Port=1812 +RadiusServer__OtpValiditySeconds=120 +RadiusServer__OtpMaxAllowedLoginAttempts=3 +RadiusServer__DuplicatePacketHandlingExpirationSeconds=120 + +# Configuration Sources (KeyValueStorage = Redis, AppSettings = Environment Variables) +RadiusServer__CustomerConfigSource=KeyValueStorage +RadiusServer__I18nMessagesSource=KeyValueStorage + +# Key-Value Storage (Redis) +Schnittstellen__KeyValueStorage__Storage=Redis +Schnittstellen__KeyValueStorage__ConnectionString=:6379,password=,ssl=False,abortConnect=False + +# MobileID Client +Schnittstellen__MobileIdClient__Host=https://mobileid.swisscom.com +Schnittstellen__MobileIdClient__ClientCertFromEnv=true +Schnittstellen__MobileIdClient__TransactionTimeoutSeconds=60 +Schnittstellen__MobileIdClient__SignatureTrust__ValidateCertTrust=true +Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignature=true +Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignaturePayload=true +Schnittstellen__MobileIdClient__ServerTrust__ValidateCertTrust=true + +# TrustStore Configuration +# Base64-encode each ROOT CA certificate (PEM format): +# $ base64 -w 0 Swisscom_Root_CA_4.cer +Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__0= +Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__1= +Schnittstellen__MobileIdClient__ServerTrust__TrustStore__0= +``` + +::: tip +The TrustStore certificates (Swisscom Root CA 4, Swisscom Root CA 2, SwissSign Gold CA-G2) are pre-encoded in the sample files available on [GitHub](https://github.com/MobileID-Strong-Authentication/mid-radius-rig). You can copy the base64 values directly from there. +::: + +### Single-Node Deployment (without Redis) + +For deployments that only use **SIM** and/or **APP** authentication (no OTP), RIG can run as a single container without Redis. In this mode, set the storage to `InMemory` and provide the customer configuration and I18N messages via environment variables: + +```bash +# Key-Value Storage (InMemory - no Redis required) +Schnittstellen__KeyValueStorage__Storage=InMemory + +# Configuration Sources (AppSettings = Environment Variables) +RadiusServer__CustomerConfigSource=AppSettings +RadiusServer__I18nMessagesSource=AppSettings +``` + +The customer configuration is then provided as indexed environment variables. See the [Configuration](/radius-interface-gateway-guide/configuration#configuration-via-environment-variables) page for the full environment variable reference. + +::: warning +OTP authentication is **not supported** without Redis, as OTP session state requires shared storage across request cycles. +::: + +## Docker Compose + +With Compose, you can create a YAML file to define the services and, with a single command, spin everything up or tear it all down. The following example starts a complete RIG cluster with all required components. + +The services are: + +- **Mobile ID RADIUS Interface Gateway application** — from [Docker Hub](https://hub.docker.com/repository/docker/mobileidch/mid-radius-rig) (or alternatively from [Amazon ECR](https://gallery.ecr.aws/mobileidch/mid-radius-rig)) +- **Redis database** using `redis` (or alternatively `keydb` may be used) +- **Redis web management tool** using `redis-commander` to manage the Redis database content (customer configs, I18N messages) +- **UDP network load balancer** using `nginx` with a custom `nginx.conf` configuration + +### docker-compose.yml + +Update `MID_CLIENT_CERTIFICATE`, `Schnittstellen__KeyValueStorage__ConnectionString`, and `Schnittstellen__MobileIdClient__Host` according to your setup. + +```yaml +services: + + mid-radius-rig: + # Option 1: Pull image from Docker Hub + image: mobileidch/mid-radius-rig:latest + # Option 2: Pull image from AWS ECR + # image: public.ecr.aws/r4c1w5d3/mid-radius-rig:latest + hostname: "rig_gateway" + ports: + - "1812/udp" + # Health check endpoint mapped to port 8055 on Docker host + - "8055:80/tcp" + links: + - redis + restart: always + environment: + - Serilog__MinimumLevel__Default=Information + - Serilog__MinimumLevel__Override__Microsoft=Warning + - Serilog__MinimumLevel__Override__Microsoft.Hosting.Lifetime=Warning + - Serilog__MinimumLevel__Override__Microsoft.Extensions.Diagnostics.HealthChecks=Error + - Serilog__MinimumLevel__Override__Flexinets.Radius.RadiusServer=Information + - Serilog__MinimumLevel__Override__Flexinets.Radius.Core=Information + - Serilog__WriteTo__0__Args__outputTemplate={Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u4} [{CorrelationId}] {SourceContext} - {Message:lj}{NewLine}{Exception} + - ASPNETCORE_ENVIRONMENT=Production + - MID_CLIENT_CERTIFICATE= + - RadiusServer__Port=1812 + - RadiusServer__OtpValiditySeconds=120 + - RadiusServer__OtpMaxAllowedLoginAttempts=3 + - RadiusServer__CustomerConfigSource=KeyValueStorage + - RadiusServer__I18nMessagesSource=KeyValueStorage + - RadiusServer__DuplicatePacketHandlingExpirationSeconds=120 + - Schnittstellen__KeyValueStorage__Storage=Redis + - Schnittstellen__KeyValueStorage__ConnectionString=redis:6379,password=,ssl=False,abortConnect=False + - Schnittstellen__MobileIdClient__Host=https://mobileid.swisscom.com + - Schnittstellen__MobileIdClient__ClientCertFromEnv=true + - Schnittstellen__MobileIdClient__SignatureTrust__ValidateCertTrust=true + - Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignature=true + - Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignaturePayload=true + - Schnittstellen__MobileIdClient__ServerTrust__ValidateCertTrust=true + - Schnittstellen__MobileIdClient__TransactionTimeoutSeconds=60 + # TrustStore certificates (see env file sample for base64 values) + - Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__0= + - Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__1= + - Schnittstellen__MobileIdClient__ServerTrust__TrustStore__0= + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/health"] + interval: 20s + retries: 3 + start_period: 10s + timeout: 3s + + redis: + image: redis:latest + container_name: "rig_redis" + hostname: "rig_redis" + ports: + - "6379:6379" + command: ["redis-server", "--appendonly", "yes"] + volumes: + - redis-data:/data + restart: always + + redis-commander: + image: rediscommander/redis-commander:latest + container_name: "rig_redis_commander" + environment: + - REDIS_HOSTS=local:redis:6379 + - HTTP_USER=admin + - HTTP_PASSWORD= + ports: + - 8081:8081 + depends_on: + - redis + restart: always + + nginx: + image: nginx:latest + container_name: "rig_nginx" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + depends_on: + - mid-radius-rig + ports: + - "11812:1812/udp" + +volumes: + redis-data: +``` + +### nginx.conf + +The following `nginx.conf` configures a UDP load balancer that forwards RADIUS traffic to the RIG container(s). Place this file in the same directory as `docker-compose.yml`. + +```nginx +user nginx; + +events { + worker_connections 1000; +} +stream { + upstream rig-nginx { + server mid-radius-rig:1812; + } + + server { + listen 1812 udp; + proxy_pass rig-nginx; + } +} +``` + +### Starting the Cluster + +Make sure that both `docker-compose.yml` and `nginx.conf` exist in the same directory, then run: + +```bash +docker-compose up --scale mid-radius-rig=3 +``` + +This starts 3 RIG instances behind the nginx UDP load balancer, with Redis for shared state. The health check endpoint is available at `http://localhost:8055/health`. + +You can verify the health check status with: + +```bash +docker inspect --format='{{json .State.Health}}' +``` + +## Integration Scenarios + +This chapter describes four different integration scenarios: + +1. [MFA with Mobile Signature](#mfa-with-mobile-signature) +2. [MFA with SMS OTP](#mfa-with-sms-otp) +3. [SFA with Mobile Signature](#sfa-with-mobile-signature) +4. [MFA with LDAP](#mfa-with-ldap) + +### MFA with Mobile Signature + +In the first scenario, a user wants to establish a VPN connection and the backend is configured to use an existing RADIUS server for user authentication and authorization, coupled with the RADIUS Interface Gateway (RIG) service for multi-factor authentication. The user is an active Mobile ID user, so a mobile signature is acquired in the process and, depending on the outcome of that signature validation, the user gets a new VPN connection established. + +VPN Authentication with MFA and Mobile Signature + +**Step 1** — The user opens the VPN client (the Supplicant) on his/her laptop and clicks on the desired VPN connection. Since the user does not want to store credentials locally, the VPN client asks for the username and password. The user enters the requested credentials. + +**Step 2** — The VPN client initiates a specific protocol connection (e.g. PPTP, L2TP/IPSec, etc.) to the VPN server, transmitting the username and password. The VPN server is configured to use RADIUS as the authentication protocol. + +**Step 3** — The VPN server creates a RADIUS Access-Request packet using its RADIUS shared secret, the username and password received from the VPN client, and the type of service the user requested: VPN. The RADIUS packet is sent to the client's backend RADIUS server. + +``` +Code: Access-Request +Identifier: 15 +Authenticator: D23B55123DB54103 +Attributes: + - NAS-Identifier: digitec-vpn-iop + - User-Name: john + - User-Password: md5("secret"+Authenticator) +``` + +**Step 4** — The RADIUS server validates all aspects of the received request: the shared secret, the user password, and permissions. It also checks if there are other extra authentication steps required for this user. It finds that this user has multi-factor authentication (MFA) enabled via Mobile ID. + +**Step 5** — To use Mobile ID as MFA, the flow needs to go through the RIG service. For this to happen, the RADIUS server needs the MSISDN of the currently authenticating user. It makes a local query to its data store and finds the MSISDN of the user based on the given username. + +An alternative at this step is for mobile users to directly enter the username as a construct of `@` (e.g. `40712345678@client.com`) and directly provide that value to the VPN client in Step 1 above. Since this username is also paired to a matching password as per the RADIUS flow, having the user enter a wrong MSISDN (by typo or intentionally) is unlikely. + +**Step 6** — The RADIUS server creates a second RADIUS Access-Request packet, similar to the one in Step 3. In this case, the RADIUS server acts as a client for the next RADIUS server in the chain: the RIG service. The packet contains the secret shared between this RADIUS server and the RIG service. The username is formatted as `@` (e.g. `40712345678@client.com`). The user password is not used at this step, so it is filled in with filler text (`not-used`). + +``` +Code: Access-Request +Identifier: 21 +Authenticator: CCEB551E2254AAB +Attributes: + - NAS-Identifier: mid-digitec-vpn + - User-Name: 40712345678@client.com + - User-Password: md5("secret"+Authenticator) +``` + +**Step 7** — The RIG service receives the request and proceeds to validate the NAS identifier and the shared secret of the client. Based on the client's configuration, the RIG service decides how to proceed and what parameters to use for the next step: + +- Based on the authentication method algorithm configured for this client, an array of possible methods is selected. These can be any of SIM-based digital signature, app-based digital signature, OTP over SMS, or any other method that will be implemented in future versions. +- From the User-Name received from the RADIUS client, the user's MSISDN is extracted. +- Based on an MSS Profile Query for the user's MSISDN, the appropriate method of authentication is selected. If the user has an active Mobile ID account, the method could be SIM- or App-based digital signature. If the user has issues with the Mobile ID account or has no such account, the chosen method could be OTP over SMS. For the current use case, the user has an active Mobile ID account, so the flow continues with a SIM/App-based digital signature authentication (see [Authentication Methods](/radius-interface-gateway-guide/introduction#authentication-methods) for more information). +- The AP ID, AP password, signature profile, and the DTBS are extracted and prepared from the client's configuration. + +**Step 8** — The RIG service connects to Mobile ID and sends the MSS Signature Request. The operation is asynchronous, so it receives an instant response along with an `AP_TransID` to use in subsequent polls. + +**Step 9** — The Mobile ID service sends a signature request to the user's mobile device (via SIM or mobile app). + +**Step 10** — The user confirms the transaction and authenticates via PIN or fingerprint. A digital signature is created on the mobile device and returned to Mobile ID. + +**Step 11** — In one of its MSS Status Query polls, the RIG service receives the response with a finished signature status and the digital signature content. + +**Step 12** — After validating the signature, the RIG service decides to accept the user's authentication request. At this point, there are no further checks performed (e.g. proper user authorization) as the RIG service is not in the position of authorizing the user. Therefore, it creates a RADIUS Access-Accept packet with an access reply message (created from the client's configuration) and sends the packet back to the RADIUS client that called it. + +``` +Code: Access-Accept +Identifier: 21 +Authenticator: cc76edab453b554cd7e7a +Attributes: + - Reply-Message: Authentication successful! +``` + +**Step 13** — The RADIUS client (i.e. the client's RADIUS server) combines the RIG service's Access-Accept packet with its internal evaluation of the user's access request and decides to accept the user's request. A new RADIUS Access-Accept packet is created and returned to the VPN server. + +``` +Code: Access-Accept +Identifier: 15 +Authenticator: ec89a776d8cdea8675ac7 +Attributes: + - Login-Service: VPN + - Reply-Message: Authentication successful! +``` + +**Step 14** — The VPN server receives the Access-Accept packet and proceeds to provide the user with the requested service (i.e. establishes the VPN connection). + +### MFA with SMS OTP + +For mobile users that do not have a Mobile ID account or have issues with their account, the RIG service can fall back to a less secure authentication method that uses a one-time password (OTP) generated by the RIG service, sent to the mobile user via an SMS text message, and then requested back in a RADIUS Access-Challenge round trip. This method can function both as a fallback method and as a main method of authentication, depending on the RADIUS client configuration at RIG service level. + +VPN Authentication with MFA and SMS OTP + +**Step 1** — The user opens the VPN client (the Supplicant) on his/her laptop and clicks on the desired VPN connection. Since the user does not want to store credentials locally, the VPN client asks for the username and password. The user enters the requested credentials. + +**Step 2** — The VPN client initiates a specific protocol connection (e.g. PPTP, L2TP/IPSec, etc.) to the VPN server, transmitting the username and password. The VPN server is configured to use RADIUS as the authentication protocol. + +**Step 3** — The VPN server creates a RADIUS Access-Request packet using its RADIUS shared secret, the username and password received from the VPN client, and the type of service the user requested: VPN. The RADIUS packet is sent to the client's backend RADIUS server. + +``` +Code: Access-Request +Authenticator: a23b55123d... +Attributes: + - NAS-Identifier: digitec-vpn-iop + - User-Name: john + - User-Password: pass4john +``` + +**Step 4** — The RADIUS server validates all aspects of the received request: the shared secret, the user password, and permissions. It also checks if there are other extra authentication steps required for this user. It finds that this user has multi-factor authentication (MFA) enabled via Mobile ID. + +**Step 5** — To use Mobile ID as MFA, the flow needs to go through the RIG service. For this to happen, the RADIUS server needs the MSISDN of the currently authenticating user. It makes a local query to its data store and finds the MSISDN of the user based on the given username. + +An alternative at this step is for mobile users to directly enter the username as a construct of `@` (e.g. `40712345678@client.com`) and directly provide that value to the VPN client in Step 1 above. Since this username is also paired to a matching password as per the RADIUS flow, having the user enter a wrong MSISDN (by typo or intentionally) is unlikely. + +**Step 6** — The RADIUS server creates a second RADIUS Access-Request packet, similar to the one in Step 3. In this case, the RADIUS server acts as a client for the next RADIUS server in the chain: the RIG service. The packet contains the secret shared between this RADIUS server and the RIG service. The username is formatted as `@` (e.g. `40712345678@client.com`). The user password is not used at this step, so it is filled in with filler text (`not-used`). + +``` +Code: Access-Request +Authenticator: d77e11123f... +Attributes: + - NAS-Identifier: mid-digitec-vpn + - User-Name: 40712345678@client.com + - User-Password: not-used +``` + +**Step 7** — The RIG service receives the request and proceeds to validate the NAS identifier and the shared secret of the client. Based on the client's configuration, the RIG service decides how to proceed and what parameters to use for the next step: + +- Based on the authentication method algorithm configured for this client, an array of possible methods is selected. These can be any of SIM-based digital signature, app-based digital signature, OTP over SMS, or any other method that will be implemented in future versions. +- From the User-Name received from the RADIUS client, the user's MSISDN is extracted. + +**Step 8** — Based on an MSS Profile Query for the user's MSISDN, the RIG service selects the OTP over SMS method (see [Authentication Methods](/radius-interface-gateway-guide/introduction#authentication-methods) for more information). + +**Step 9** — An OTP code is generated to function as the challenge request to the user. The content of the challenge message is loaded from the client's configuration. + +**Step 10** — The RIG service connects to Mobile ID and sends an MSS Signature Request with the signature profile set to `http://mid.swisscom.ch/MID/v1/OtpProfileText` (SMS text message via Mobile ID). + +**Step 11** — On its side, the Mobile ID service connects to the GSM gateway and transmits the SMS text message to the mobile user's device. + +**Step 12** — The user receives the SMS text message on his/her phone. + +**Step 13** — After sending the SMS text message, the RIG service assembles a RADIUS Access-Challenge response, with the reply message set to inform the user on how to proceed with the challenge. + +``` +Code: Access-Challenge +Authenticator: cde679ab... +Attributes: + - Reply-Message: Please enter the code received by SMS on your phone! +``` + +**Step 14** — The RADIUS server passes the Access-Challenge response to the VPN server which, in turn, sends the challenge content to the VPN client that runs on the user's machine. The VPN client prompts the user to enter the challenge response. In the prompt window, the application displays the challenge text to inform the user how to proceed. + +**Step 15** — The user checks the phone and enters the OTP code received by SMS into the application prompt. + +**Step 16** — The entered OTP code is sent back point-to-point, from the VPN application to the VPN server and then to the RADIUS server, via a new RADIUS Access-Request, which this time has the User-Password set to contain the encrypted value of the OTP code. + +**Step 17** — On the RADIUS server side, the request from the client is again validated using the shared secret and the ongoing authentication session is identified. + +**Step 18** — The challenge response is packaged again in a new RADIUS Access-Request and sent to the RIG service. + +**Step 19** — On the RIG service's side, the incoming request is validated and the ongoing authentication session is identified. The decrypted OTP code is checked against the one stored in the authentication session. + +**Step 20** — Since the received OTP matches the one stored in the authentication session, the RIG service decides to accept the user's authentication request. At this point, there are no further checks performed (e.g. proper user authorization) as the RIG service is not in the position of authorizing the user. Therefore, it creates a RADIUS Access-Accept packet with an access reply message (created from the client's configuration) and sends the packet back to the RADIUS client that called it. + +``` +Code: Access-Accept +Authenticator: dede679ab... +Attributes: + - Reply-Message: Login successful! +``` + +**Step 21** — The RADIUS client (i.e. the client's RADIUS server) combines the RIG service's Access-Accept packet with its internal evaluation of the user's access request and decides to accept the user's request. A new RADIUS Access-Accept packet is created and returned to the VPN server. + +``` +Code: Access-Accept +Authenticator: 88e4e17ab3d... +Attributes: + - Login-Service: VPN + - Login-TCP-Port: 1194 + - Reply-Message: Login successful! +``` + +**Step 22** — The VPN server receives the Access-Accept packet and proceeds to provide the user with the requested service (i.e. establishes the VPN connection). + +### SFA with Mobile Signature + +For this scenario, the client's architecture relies on a single RADIUS service to perform user authentication: the RIG service. This makes Mobile ID function as a single-factor authentication, in the context of authentication steps that users must go through to obtain access to the desired services. + +VPN Authentication with SFA and Mobile Signature + + +**Step 2** — The VPN client initiates a specific protocol connection (e.g. PPTP, L2TP/IPSec, etc.) to the VPN server, transmitting the username and password. The VPN server is configured to use RADIUS as the authentication protocol. + +**Step 3** — The VPN server creates a RADIUS Access-Request packet using its RADIUS shared secret, the username and password received from the VPN client, and the type of service the user requested: VPN. The RADIUS packet is sent to the RIG service for processing. + +``` +Code: Access-Request +Authenticator: A23B55123DB54103 +Attributes: + - NAS-Identifier: mid-digitec-vpn + - User-Name: 40712345678@client.com + - User-Password: not-used +``` + +**Step 4** — The RIG service receives the request and proceeds to validate the NAS identifier and the shared secret of the client. Based on the client's configuration, the RIG service decides how to proceed and what parameters to use for the next step: + +- Based on the authentication method algorithm configured for this client, an array of possible methods is selected. These can be any of SIM-based digital signature, app-based digital signature, OTP over SMS, or any other method that will be implemented in future versions. +- From the User-Name received from the RADIUS client, the user's MSISDN is extracted. +- Based on an MSS Profile Query for the user's MSISDN, the appropriate method of authentication is selected. If the user has an active Mobile ID account, the method could be SIM- or App-based digital signature. If the user has issues with the Mobile ID account or has no such account, the chosen method could be OTP over SMS. For the current use case, the user has an active Mobile ID account, so the flow continues with a SIM/App-based digital signature authentication (see [Authentication Methods](/radius-interface-gateway-guide/introduction#authentication-methods) for more information). +- The AP ID, AP password, signature profile, and the DTBS are extracted and prepared from the client's configuration. + +**Step 5** — The RIG service connects to Mobile ID and sends the MSS Signature Request. The operation is asynchronous, so it receives an instant response along with an `AP_TransID` to use in subsequent polls. On its side, the Mobile ID service sends a signature request to the user's mobile device (via SIM or mobile app). + +**Step 6** — The user confirms the transaction and authenticates via PIN or fingerprint. A digital signature is created on the mobile device and returned to Mobile ID. + +**Step 7** — In one of its MSS Status Query polls, the RIG service receives the response with a finished signature status and the digital signature content. + +**Step 8** — After validating the signature, the RIG service decides to accept the user's authentication request. At this point, there are no further checks performed (e.g. proper user authorization) as the RIG service is not in the position of authorizing the user. Therefore, it creates a RADIUS Access-Accept packet with an access reply message (created from the client's configuration) and sends the packet back to the RADIUS client (i.e. VPN server) that called it. + +``` +Code: Access-Accept +Identifier: 15 +Authenticator: ec89a776d8cdea8675ac7 +Attributes: + - Login-Service: VPN + - Reply-Message: Authentication successful! +``` + +**Step 9** — The VPN server receives the Access-Accept packet and proceeds to provide the user with the requested service (i.e. establishes the VPN connection). + +### MFA with LDAP + +This scenario presents a setup where the RIG service is configured as the only RADIUS server in a client's network. It uses a local LDAP directory instance for validating the user's credentials and the Mobile ID service for second-factor authentication via a mobile signature. In this scenario, the MSISDN is not sent as part of the RADIUS User-Name attribute but is resolved by the RIG service via the LDAP directory. + +VPN Authentication with MFA, LDAP, and Mobile Signature + +**Step 1** — The user opens the VPN client (the Supplicant) on his/her laptop and clicks on the desired VPN connection. Since the user does not want to store credentials locally, the VPN client asks for the username and password. The user enters the username (e.g. `jack@client.com`) and the password. + +**Step 2** — The VPN client initiates a specific protocol connection (e.g. PPTP, L2TP/IPSec, etc.) to the VPN server, transmitting the username and password. The VPN server is configured to use RADIUS as the authentication protocol. + +**Step 3** — The VPN server creates a RADIUS Access-Request packet using its RADIUS shared secret, the username and password received from the VPN client, and the type of service the user requested: VPN. The RADIUS packet is sent to the RIG service for processing. + +``` +Code: Access-Request +Authenticator: A23B55123DB54103 +Attributes: + - NAS-Identifier: mid-digitec-vpn + - User-Name: jack@client.com + - User-Password: s3cr3t +``` + +**Step 4** — The RIG service receives the request and proceeds to validate the NAS identifier and the shared secret of the client. + +**Step 5** — Based on the client's configuration, the RIG service performs a query on the configured LDAP directory, retrieving the user password and MSISDN based on the received username. + +**Step 6** — The retrieved LDAP data is used in this step to perform the first-factor authentication: validate the user-supplied password. + +**Step 7** — Based on an MSS Profile Query for the user's MSISDN, the appropriate method of authentication is selected. If the user has an active Mobile ID account, the method could be SIM- or App-based digital signature. If the user has issues with the Mobile ID account or has no such account, the chosen method could be OTP over SMS. For the current use case, the user has an active Mobile ID account, so the flow continues with a SIM/App-based digital signature authentication (see [Authentication Methods](/radius-interface-gateway-guide/introduction#authentication-methods) for more information). The AP ID, AP password, signature profile, and the DTBS are extracted and prepared from the client's configuration. + +**Step 8** — The RIG service connects to Mobile ID and sends the MSS Signature Request. The operation is asynchronous, so it receives an instant response along with an `AP_TransID` to use in subsequent polls. On its side, the Mobile ID service sends a signature request to the user's mobile device (via SIM or mobile app). + +**Step 9** — The user confirms the transaction and authenticates via PIN or fingerprint. A digital signature is created on the mobile device and returned to Mobile ID. + +**Step 10** — In one of its MSS Status Query polls, the RIG service receives the response with a finished signature status and the digital signature content. + +**Step 11** — After validating the signature, the RIG service decides to accept the user's authentication request. At this point, there are no further checks performed (e.g. proper user authorization) as the RIG service is not in the position of authorizing the user. Therefore, it creates a RADIUS Access-Accept packet with an access reply message (created from the client's configuration) and sends the packet back to the RADIUS client (i.e. VPN server) that called it. + +``` +Code: Access-Accept +Identifier: 15 +Authenticator: ec89a776d8cdea8675ac7 +Attributes: + - Login-Service: VPN + - Reply-Message: Authentication successful! +``` + +**Step 12** — The VPN server receives the Access-Accept packet and proceeds to provide the user with the requested service (i.e. establishes the VPN connection). + +## SMS Notifications + +The most secure authentication method for users is to use Mobile ID with SIM- or app-based digital signatures. This, however, requires an active Mobile ID account, which is something that users might not have immediately available during a RADIUS authentication session. For this reason, after an authentication session is finished successfully (say, with a fallback to OTP over SMS, where the OTP is correctly provided by the user), the RIG service will follow up with the respective user with an SMS notification to help the user kick-start the process of fixing the issue with the Mobile ID account (or create an account altogether). + +The RIG service cannot provide the UI required for fixing any account issues or guide the user into creating a new Mobile ID account. For these reasons, the SMS text sent as a delayed notification will contain a friendly message adapted to the respective account situation and a link to the Mobile ID user portal where the user can create a new account or fix any existing issues. + +For each RADIUS client configured for the RIG service, the following delayed notifications are available: + +| Account Situation | Notification Message | +|---|---| +| No Mobile ID account | "Create a new Mobile ID account by visiting the Mobile ID portal. `https://link`" | +| Account present, not active | "You can activate your Mobile ID account by visiting the Mobile ID portal. `https://link`" | +| Account present, PIN blocked | "We noticed your Mobile ID account has its PIN blocked. Visit the Mobile ID portal to unblock it. `https://link`" | + +These messages are configurable on a per-client basis, including the template for each of the four supported Mobile ID languages, the time between notifications, and the total number of SMS messages to send per user (to prevent user spamming). + +## LDAP Authentication + +In the previous chapters, we discussed various service setups, one of which could have the RIG service installed on the client's premises (either physical premises or client-managed cloud environment). For this setup, if the RIG service needs to act as the main (or only) RADIUS server, it needs to perform both username + password authentication and the second-factor authentication via Mobile ID. To accomplish this, one option is to enable the RIG service to validate user's credentials against an LDAP server. + +The following diagram presents this setup: + +RIG LDAP authentication setup + +By configuration, the RIG service can connect to a local LDAP server and validate the received RADIUS User-Name and User-Password against a set of LDAP user attributes. Once this validation is successful, the service can move to the Mobile ID-based authentication part of the flow. + +This feature allows the RIG service to be a quick drop-in replacement for the existing RADIUS server for clients that already have this combination (RADIUS + LDAP database). + +--- + +## RADIUS Configuration + +Source: https://docs.mobileid.ch/radius-interface-gateway-guide/configuration.html + +# Configuration + +This page describes how to configure the RIG application for your environment. RIG supports two configuration sources: + +| Source | Storage | Best for | +|--------|---------|----------| +| **KeyValueStorage** (Redis) | Customer configs and I18N messages stored as JSON in Redis | Production / multi-node clusters | +| **AppSettings** (Environment Variables) | All configuration provided via environment variables | Single-node deployments without Redis | + +The configuration source is controlled by these environment variables: + +```bash +# Set to 'KeyValueStorage' (Redis) or 'AppSettings' (Environment Variables) +RadiusServer__CustomerConfigSource=KeyValueStorage +RadiusServer__I18nMessagesSource=KeyValueStorage +``` + +## Customer Configuration (Redis) + +When using Redis, add the customer configuration as a JSON string to your Redis database: + +- **Key:** `CUSTOMER_CONFIG_` (e.g., `CUSTOMER_CONFIG_mid://ap.mycompany.ch`) +- **Value:** JSON string (see example below) + +You may configure one or multiple customers. Each customer should have its own Mobile ID account (`ApId`) for separate usage and billing reporting. + +### Request Mapping + +An incoming RADIUS `Access-Request` packet is mapped to the correct customer configuration as follows: + +1. RIG first tries to match the packet's **source IP address** against any `SourceIps` entries in the customer configurations. +2. If no source IP matches, RIG tries to match the inbound `NAS-Identifier` attribute against the `NasIdentifier` entries. + +Ensure each customer configuration has either unique `SourceIps` entries or a unique `NasIdentifier` entry. + +### Customer Configuration Example + +```json +{ + "Customer": "My Company XYZ", + "ApId": "mid://ap.mycompany.ch", + "NasIdentifier": "ch_mycompany", + "SourceIps": [ + "10.1.1.22/32" + ], + "RadiusSharedSecret": "MyVeryStrongSharedSecret", + "AccountingWebhook": { + "Url": "https://my-webhook.example.com/accounting", + "HttpMethod": "POST" + }, + "UseLdap": true, + "Ldap": { + "Hosts": { + "Primary": "10.0.0.5", + "Secondary": "", + "Tertiary": "" + }, + "Port": 389, + "ConnectionTimeoutSeconds": 20, + "EnableSsl": false, + "AdminUser": "cn=admin,dc=mycompany,dc=ch", + "AdminPassword": "MyAdminPassword", + "UseClientCredentialsForConnection": false, + "FollowReferrals": false, + "DefaultSearchScope": "LDAP_SCOPE_SUBTREE", + "CheckUserAccountControl": false, + "UserSearchBase": "ou=users,dc=mycompany,dc=ch", + "UserSearchFilter": "(&(objectclass=person)(|(sAMAccountName={username})(userPrincipalName={username})))", + "UserGroupSearchFilter": "(&(objectClass=groupOfNames)(member={userdn}))", + "ValidateUserPassword": true, + "MobileNrAttribute": "mobile", + "LanguageAttribute": "preferredLanguage", + "SerialNrAttribute": "msNPCallingStationID", + "MfaMethod": { + "MappingType": "Attribute", + "AttributeName": "mfa_type", + "Mappings": { + "Sim": "LDAP_SIM_VALUE", + "App": "LDAP_APP_VALUE", + "Otp": "LDAP_OTP_VALUE", + "None": "LDAP_NONE_VALUE" + } + }, + "ClassMatching": { + "ClassMappings": [ + { + "GroupDn": "cn=readers,ou=users,dc=example,dc=org", + "ClassName": "Group Policy A" + }, + { + "GroupDn": "cn=admins,ou=users,dc=example,dc=org", + "ClassName": "Group Policy B" + } + ] + } + }, + "Geofencing": { + "Activate": true, + "Whitelist": ["CH", "DE"], + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7 + }, + "DefaultLanguage": "en", + "ValidateSerialNr": false, + "UseUserLanguage": false, + "UseUserMfaMethod": true, + "MfaMethods": ["SIM", "APP", "OTP", "NONE"], + "Otp": { + "Length": 5, + "Mode": "Text", + "SmsText": { + "Default": "Ihr MobileID Code ist {0}", + "De": "Ihr MobileID Code ist {0}", + "Fr": "Votre MobileID Code est {0}", + "It": "Il MobileID Code è {0}", + "En": "Your MobileID Code is {0}" + }, + "ReplyMessageText": { + "Default": "Geben Sie den Code ein, den Sie per SMS erhalten haben", + "De": "Geben Sie den Code ein, den Sie per SMS erhalten haben", + "Fr": "Saisissez le code que vous avez reçu par SMS", + "It": "Inserisci il codice che hai ricevuto via SMS", + "En": "Enter the code you have received by SMS" + } + }, + "SimApp": { + "DisplayText": { + "Default": "MobileID: Bitte mit Mobile ID authentifizieren", + "De": "MobileID: Bitte mit Mobile ID authentifizieren", + "Fr": "MobileID: Veuillez vous authentifier avec votre ID mobile", + "It": "MobileID: Si prega di autenticarsi con il Mobile ID", + "En": "MobileID: Please authenticate with Mobile ID" + } + }, + "Events": { + "UnusedMidServiceEvent": { + "ExecutionDelayMinutes": 3, + "NotificationIntervalDays": 7, + "AppSmsText": { + "Default": "Please visit https://mobileid.ch/activate and activate the MobileID App", + "De": "Bitte besuchen Sie https://mobileid.ch/activate und aktivieren Sie die MobileID App", + "Fr": "Veuillez visiter https://mobileid.ch/activate et activer l'application MobileID", + "It": "Visita https://mobileid.ch/activate e attiva l'app MobileID", + "En": "Please visit https://mobileid.ch/activate and activate the MobileID App" + }, + "SimSmsText": { + "Default": "Please visit https://mobileid.ch/activate and activate your MobileID SIM card", + "De": "Bitte besuchen Sie https://mobileid.ch/activate und aktivieren Sie Ihre MobileID SIM-Karte", + "Fr": "Veuillez visiter https://mobileid.ch/activate et activer votre carte SIM MobileID", + "It": "Visita https://mobileid.ch/activate e attiva la tua SIM MobileID", + "En": "Please visit https://mobileid.ch/activate and activate your MobileID SIM card" + } + }, + "ErrorNotificationEvent": { + "ExecutionDelayMinutes": 0, + "HandledErrorCodes": [ + { + "ErrorCode": "RigSerialNumberMismatch", + "NotificationIntervalDays": 1, + "SmsText": { + "Default": "Your MobileID Token has changed. Please re-register your MobileID.", + "De": "Ihr MobileID Token hat sich geändert. Bitte registrieren Sie Ihr MobileID erneut.", + "Fr": "Votre jeton MobileID a changé. Veuillez réenregistrer votre MobileID.", + "It": "Il tuo token MobileID è cambiato. Registra nuovamente il tuo MobileID.", + "En": "Your MobileID Token has changed. Please re-register your MobileID." + } + } + ] + } + } +} +``` + +The following sections explain each configuration area in detail. + +## General Settings + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Customer` | string | Display name for the customer | +| `ApId` | string | Mobile ID Application Provider ID (e.g., `mid://ap.mycompany.ch`) | +| `NasIdentifier` | string | RADIUS NAS identifier for matching incoming requests | +| `SourceIps` | string[] | Allowed source IP addresses/ranges in CIDR notation (e.g., `10.1.1.22/32`) | +| `RadiusSharedSecret` | string | RADIUS shared secret for authenticating RADIUS packets | +| `DefaultLanguage` | string | Default language code: `de`, `fr`, `it`, or `en` | +| `ValidateSerialNr` | boolean | Validate user's Mobile ID serial number against LDAP attribute | +| `UseUserLanguage` | boolean | Load the user's language preference from LDAP | +| `UseUserMfaMethod` | boolean | Load the user's preferred MFA method from LDAP | +| `MfaMethods` | string[] | Ordered list of allowed MFA methods: `SIM`, `APP`, `OTP`, `NONE` | +| `UseLdap` | boolean | Enable LDAP integration for user attribute lookup | + +### Accounting Webhook + +Forward RADIUS accounting traffic to an external system: + +```json +"AccountingWebhook": { + "Url": "https://my-webhook.example.com/accounting", + "HttpMethod": "POST" +} +``` + +## LDAP Configuration + +The LDAP section configures how RIG connects to your directory service to retrieve user attributes. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Hosts.Primary` | string | Primary LDAP server hostname or IP address | +| `Hosts.Secondary` | string | Secondary (failover) LDAP server | +| `Hosts.Tertiary` | string | Tertiary (failover) LDAP server | +| `Port` | integer | LDAP port (`389` for LDAP, `636` for LDAPS) | +| `ConnectionTimeoutSeconds` | integer | Connection timeout in seconds | +| `EnableSsl` | boolean | Enable SSL/TLS for LDAP connections | +| `AdminUser` | string | Service account DN for LDAP queries | +| `AdminPassword` | string | Service account password | +| `UseClientCredentialsForConnection` | boolean | Use the RADIUS client's credentials instead of the admin user for LDAP connection | +| `FollowReferrals` | boolean | Follow LDAP referrals | +| `DefaultSearchScope` | string | LDAP search scope (e.g., `LDAP_SCOPE_SUBTREE`) | +| `CheckUserAccountControl` | boolean | Check Active Directory's `userAccountControl` attribute to verify the account is active | +| `UserSearchBase` | string | Base DN for user searches (e.g., `ou=users,dc=mycompany,dc=ch`) | +| `UserSearchFilter` | string | LDAP search filter with placeholders (see below) | +| `UserGroupSearchFilter` | string | LDAP filter for retrieving group memberships | +| `ValidateUserPassword` | boolean | Validate the user's password against LDAP | +| `MobileNrAttribute` | string | LDAP attribute containing the user's phone number (MSISDN) | +| `LanguageAttribute` | string | LDAP attribute for user's preferred language | +| `SerialNrAttribute` | string | LDAP attribute for Mobile ID serial number | + +### Search Filter Placeholders + +The following placeholders can be used in LDAP search filters: + +| Placeholder | Description | +|-------------|-------------| +| `{username}` | The username part from the RADIUS `User-Name` attribute (before `@`) | +| `{domain}` | The domain part from the RADIUS `User-Name` attribute (after `@`) | +| `{userdn}` | The full DN of the user (available after the initial user search) | + +**Example search filters:** + +``` +# Active Directory (sAMAccountName or UPN) +(&(objectclass=person)(|(sAMAccountName={username})(userPrincipalName={username}))) + +# OpenLDAP (uid) +(&(objectclass=inetOrgPerson)(uid={username}{domain})) + +# Group membership search +(&(objectClass=groupOfNames)(member={userdn})) +``` + +## MFA Method Mapping + +The MFA method for each user can be determined in two ways: + +### Option 1: LDAP Attribute Mapping + +Map an LDAP attribute value to an MFA method: + +```json +"MfaMethod": { + "MappingType": "Attribute", + "AttributeName": "mfa_type", + "Mappings": { + "Sim": "LDAP_SIM_VALUE", + "App": "LDAP_APP_VALUE", + "Otp": "LDAP_OTP_VALUE", + "None": "LDAP_NONE_VALUE" + } +} +``` + +Replace the `LDAP_*_VALUE` strings with the actual attribute values used in your LDAP directory. + +### Option 2: LDAP Group DN Mapping + +Map LDAP group membership to an MFA method: + +```json +"MfaMethod": { + "MappingType": "GroupDn", + "Mappings": { + "Sim": "cn=mfa-sim,ou=groups,dc=example,dc=org", + "App": "cn=mfa-app,ou=groups,dc=example,dc=org", + "Otp": "cn=mfa-otp,ou=groups,dc=example,dc=org", + "None": "cn=mfa-none,ou=groups,dc=example,dc=org" + } +} +``` + +## RADIUS Class Attribute Mapping + +The RADIUS `Class` attribute can be included in `Access-Accept` responses based on LDAP group membership. This is useful for applying policies on the RADIUS client side. + +```json +"ClassMatching": { + "ClassMappings": [ + { + "GroupDn": "cn=admins,ou=groups,dc=example,dc=org", + "ClassName": "Admin Policy" + }, + { + "GroupDn": "cn=users,ou=groups,dc=example,dc=org", + "ClassName": "Standard Policy" + } + ] +} +``` + +When a user is a member of a matching LDAP group, the corresponding `ClassName` is included as the `Class` attribute in the RADIUS `Access-Accept` response. + +## Geofencing + +RIG supports geofencing to restrict authentication based on the user's geographic location. There are two modes: **simple** (country whitelist/blacklist) and **LDAP-based** (geofencing rules managed in the directory). + +### Simple Geofencing + +Define a whitelist or blacklist of ISO country codes: + +::: code-group + +```json [Whitelist] +"Geofencing": { + "Activate": true, + "Whitelist": ["CH", "DE", "FR", "IT", "AT"], + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7 +} +``` + +```json [Blacklist] +"Geofencing": { + "Activate": true, + "Blacklist": ["US", "CN", "RU"], + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7 +} +``` + +::: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Activate` | boolean | Enable or disable geofencing | +| `Whitelist` | string[] | ISO country codes that are allowed (mutually exclusive with `Blacklist`) | +| `Blacklist` | string[] | ISO country codes that are blocked (mutually exclusive with `Whitelist`) | +| `MinimalDeviceConfidence` | decimal | Minimum device confidence score (0.0–1.0) | +| `MinimalLocationConfidence` | decimal | Minimum location confidence score (0.0–1.0) | + +::: warning +`Whitelist` and `Blacklist` are mutually exclusive — define one or the other, not both. +::: + +### LDAP-Based Geofencing + +For more granular control, geofencing rules can be managed in the LDAP directory. This allows different whitelist/blacklist rules per user group. + +```json +"Ldap": { + "Geofencing": { + "Activate": true, + "GeofencingSearchBase": "dc=mycompany,dc=ch", + "UserGeoGroupSearchFilter": "(&(objectClass=groupOfNames)(member={userdn})(ou=geo-groups))", + "CountriesSearchFilter": "(objectClass=country)", + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7, + "FailAuthIfGroupMissing": true, + "BlacklistGroupPrefix": "blacklist-", + "WhitelistGroupPrefix": "whitelist-" + } +} +``` + +| Parameter | Type | Description | +|-----------|------|-------------| +| `GeofencingSearchBase` | string | Base DN for geofencing group searches | +| `UserGeoGroupSearchFilter` | string | LDAP filter to find the user's geofencing group | +| `CountriesSearchFilter` | string | LDAP filter to find country entries within a group | +| `FailAuthIfGroupMissing` | boolean | Reject authentication if the user is not in any geofencing group | +| `BlacklistGroupPrefix` | string | Prefix for blacklist group names (e.g., `blacklist-`) | +| `WhitelistGroupPrefix` | string | Prefix for whitelist group names (e.g., `whitelist-`) | + +## Fortinet VSA Support + +RIG supports Fortinet Vendor Specific Attributes (VSA) to enrich RADIUS `Access-Accept` responses with Fortinet-specific attributes. This is useful when RIG is used together with FortiGate firewalls. + +The FortiGate behaviour is triggered when: +1. The Vendor Specific Attribute `Fortinet-Vdom-Name` is present in the incoming RADIUS `Access-Request` packet +2. The value of `Fortinet-Vdom-Name` matches the configured `VendorSpecificAttributeTriggerValue` + +### Configuration Example + +Add the `FortigateBehaviour` section inside the `Ldap` configuration: + +```json +"Ldap": { + "UserGroupSearchFilter": "(&(objectClass=groupOfNames)(member={userdn}))", + "FortigateBehaviour": { + "VendorSpecificAttributeTriggerValue": "root", + "FortinetLdapUserGroupMap": [ + { + "ForitnetGroupName": "gu-rad_msrl_sslvpn1", + "LdapGroupDn": "cn=Admin,ou=Groups,dc=example,dc=local" + }, + { + "ForitnetGroupName": "gu-rad_msrl_sslvpn2", + "LdapGroupDn": "cn=Viewer,ou=Groups,dc=example,dc=local" + } + ], + "FortinetAccessProfile": "none", + "DefaultFortinetGroupName": "no-group-found", + "FailAuthIfGroupUnknown": false + } +} +``` + +::: info +The property name `ForitnetGroupName` (note the spelling) is the actual field name used by the application. The LDAP `UserGroupSearchFilter` used for the Fortinet group lookup is defined at the `Ldap` level (not inside `FortigateBehaviour`). +::: + +### Behaviour + +After authenticating the user, RIG reads out all LDAP user groups and matches them against the `FortinetLdapUserGroupMap` entries. The **first matching group** is used. + +**If a matching group is found**, the `Access-Accept` response is enriched with: + +| Attribute | Value | +|-----------|-------| +| `Fortinet-Vdom-Name` | Value from the incoming `Access-Request` (e.g., `root`) | +| `Fortinet-Group-Name` | The matching `ForitnetGroupName` value | +| `Fortinet-Access-Profile` | The configured `FortinetAccessProfile` value | + +**If no matching group is found:** + +- If `FailAuthIfGroupUnknown` is `true`: the authentication is rejected +- If `FailAuthIfGroupUnknown` is `false`: the `Access-Accept` is enriched with the `DefaultFortinetGroupName` + +## OTP Configuration + +Configure the One-Time Password behaviour for SMS-based authentication: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Length` | integer | Number of digits in the OTP (e.g., `5`) | +| `Mode` | string | OTP mode (`Text`) | +| `SmsText` | object | Multi-language SMS text template. Use `{0}` as placeholder for the OTP value | +| `ReplyMessageText` | object | Multi-language prompt text for the RADIUS `Access-Challenge` response | + +## SIM/APP Display Text + +Configure the text displayed on the user's mobile device during SIM or APP authentication: + +```json +"SimApp": { + "DisplayText": { + "Default": "MobileID: Please authenticate with Mobile ID", + "De": "MobileID: Bitte mit Mobile ID authentifizieren", + "Fr": "MobileID: Veuillez vous authentifier avec votre ID mobile", + "It": "MobileID: Si prega di autenticarsi con il Mobile ID", + "En": "MobileID: Please authenticate with Mobile ID" + } +} +``` + +::: tip +The `DisplayText` value is shown to the user on their mobile device. You can prefix it with your company or application name (e.g., `MyCompany VPN: Please authenticate with Mobile ID`). +::: + +## SMS Event Notifications + +RIG can send SMS notifications to users in specific situations. All event notifications are optional. + +### Unused Mobile ID Service Event + +After a successful authentication that fell back to OTP (because the user has no active Mobile ID SIM or APP), RIG can send an SMS notification to encourage the user to activate their Mobile ID account. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `ExecutionDelayMinutes` | integer | Delay in minutes before sending the notification | +| `NotificationIntervalDays` | integer | Minimum days between notifications to the same user | +| `AppSmsText` | object | Multi-language SMS text when SIM is **not** Mobile ID-compliant (suggest App activation) | +| `SimSmsText` | object | Multi-language SMS text when SIM **is** Mobile ID-compliant (suggest SIM activation) | + +### Error Notification Event + +Send an SMS notification to the user when a specific error occurs during authentication (e.g., serial number mismatch, geofencing error). + +```json +"ErrorNotificationEvent": { + "ExecutionDelayMinutes": 0, + "HandledErrorCodes": [ + { + "ErrorCode": "RigSerialNumberMismatch", + "NotificationIntervalDays": 1, + "SmsText": { + "Default": "Your MobileID Token has changed. Please re-register.", + "De": "Ihr MobileID Token hat sich geändert. Bitte registrieren Sie sich erneut.", + "Fr": "Votre jeton MobileID a changé. Veuillez vous réenregistrer.", + "It": "Il tuo token MobileID è cambiato. Registrati nuovamente.", + "En": "Your MobileID Token has changed. Please re-register." + } + }, + { + "ErrorCode": "MidGeo_100", + "NotificationIntervalDays": 1, + "SmsText": { + "Default": "Please enable the Geofencing toggle in your MobileID App.", + "De": "Bitte aktivieren Sie den Geofencing-Schalter in Ihrer MobileID App.", + "Fr": "Veuillez activer le commutateur de géorepérage dans votre application MobileID.", + "It": "Abilita l'interruttore di geofencing nella tua app MobileID.", + "En": "Please enable the Geofencing toggle in your MobileID App." + } + } + ] +} +``` + +## I18N Error Messages + +The I18N error message configuration allows you to customize the `Reply-Message` content in RADIUS `Access-Reject` responses. Messages are defined per error code in four languages (German, French, Italian, English). + +### Configuration via Redis + +Add the I18N messages as a JSON array to Redis: + +- **Key:** `I18N_MESSAGES` +- **Value:** JSON array (see example below) + +::: info +The RIG application must be restarted after an I18N configuration change in Redis. +::: + +```json +[ + { + "Key": "DefaultErrorMessage", + "De": "Authentifizierung fehlgeschlagen", + "Fr": "Échec de l'authentification", + "It": "Autenticazione non riuscita", + "En": "Authentication failed" + }, + { + "Key": "Mid_105", + "De": "Diese Rufnummer ist keine bekannte MobileID-Nummer.", + "Fr": "Ce numéro de téléphone n'est pas un numéro MobileID connu.", + "It": "Questo numero di telefono non è un numero MobileID conosciuto.", + "En": "This phone number is an unknown MobileID number." + }, + { + "Key": "Mid_208", + "De": "Die MobileID-Sitzung ist abgelaufen. Bitte versuchen Sie es erneut.", + "Fr": "La session MobileID a expiré. Veuillez réessayer.", + "It": "La sessione MobileID è scaduta. Riprova.", + "En": "The MobileID authentication session has expired. Please try again." + }, + { + "Key": "Mid_401", + "De": "Die MobileID-Authentifizierung wurde vom Benutzer abgebrochen.", + "Fr": "L'authentification MobileID a été annulée par l'utilisateur.", + "It": "L'autenticazione MobileID è stata annullata dall'utente.", + "En": "The MobileID authentication was cancelled by the user." + }, + { + "Key": "Mid_402", + "De": "Die MobileID-PIN ist gesperrt. Besuchen Sie https://mobileid.ch/reset um sie zurückzusetzen.", + "Fr": "Le PIN MobileID est bloqué. Visitez https://mobileid.ch/reset pour le réinitialiser.", + "It": "Il PIN MobileID è bloccato. Visita https://mobileid.ch/reset per reimpostarlo.", + "En": "The MobileID PIN is blocked. Please visit https://mobileid.ch/reset to reset it." + }, + { + "Key": "Mid_404", + "De": "Kein aktives MobileID gefunden. Besuchen Sie https://mobileid.ch/activate zur Aktivierung.", + "Fr": "Aucun MobileID actif trouvé. Visitez https://mobileid.ch/activate pour l'activer.", + "It": "Nessun MobileID attivo trovato. Visita https://mobileid.ch/activate per attivarlo.", + "En": "No active MobileID found. Please visit https://mobileid.ch/activate to activate." + }, + { + "Key": "Mid_406", + "De": "Es läuft bereits eine MobileID-Authentifizierung. Bitte warten und erneut versuchen.", + "Fr": "Une authentification MobileID est déjà en cours. Veuillez patienter et réessayer.", + "It": "Un'autenticazione MobileID è già in corso. Attendere e riprovare.", + "En": "There is already a MobileID authentication on-going. Please wait and try again." + }, + { + "Key": "Mid_422", + "De": "Kein aktives MobileID gefunden. Besuchen Sie https://mobileid.ch/activate zur Aktivierung.", + "Fr": "Aucun MobileID actif trouvé. Visitez https://mobileid.ch/activate pour l'activer.", + "It": "Nessun MobileID attivo trovato. Visita https://mobileid.ch/activate per attivarlo.", + "En": "No active MobileID found. Please visit https://mobileid.ch/activate to activate." + }, + { + "Key": "LdapInvalidCredentials", + "De": "LDAP-Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihre Zugangsdaten.", + "Fr": "Échec de l'authentification LDAP. Veuillez vérifier vos identifiants.", + "It": "Autenticazione LDAP non riuscita. Verificare le credenziali.", + "En": "LDAP user authentication failed. Please verify your credentials and try again." + }, + { + "Key": "LdapUserNotFound", + "De": "LDAP-Benutzer nicht gefunden. Bitte überprüfen Sie Ihre Zugangsdaten.", + "Fr": "Utilisateur LDAP introuvable. Veuillez vérifier vos identifiants.", + "It": "Utente LDAP non trovato. Verificare le credenziali.", + "En": "LDAP user not found. Please verify your credentials and try again." + }, + { + "Key": "RigOtpMismatch", + "De": "Das eingegebene Einmalpasswort ist ungültig.", + "Fr": "Le mot de passe à usage unique saisi est invalide.", + "It": "La password monouso inserita non è valida.", + "En": "The One-Time-Password entered is invalid." + }, + { + "Key": "RigOtpMaxAllowedLoginAttemptsExeeded", + "De": "Die maximale Anzahl an OTP-Anmeldeversuchen wurde überschritten.", + "Fr": "Le nombre maximum de tentatives de connexion OTP a été dépassé.", + "It": "Il numero massimo di tentativi di accesso OTP è stato superato.", + "En": "The maximum number of OTP login attempts has been exceeded." + }, + { + "Key": "RigLocationValidationFailed", + "De": "Der aktuelle Standort ist nicht erlaubt.", + "Fr": "L'emplacement actuel n'est pas autorisé.", + "It": "La posizione attuale non è consentita.", + "En": "The user's current country code is not allowed." + } +] +``` + +### Supported Error Codes + +The following error codes can be used in both the I18N error message configuration and the error notification events: + +#### Mobile ID Errors + +| Error Code | Description | +|------------|-------------| +| `Mid_{code}` | Any 3-digit Mobile ID API error code (e.g., `Mid_401`, `Mid_404`). Refer to the Mobile ID Client Reference Guide. | +| `MidGeo_{code}` | Any 3-digit Mobile ID Geofencing error code (e.g., `MidGeo_100`). Refer to the Mobile ID Client Reference Guide. | +| `MidInvalidSerialNumber` | The Mobile ID serial number from the signature response is invalid | + +#### LDAP Errors + +| Error Code | Description | +|------------|-------------| +| `LdapInvalidCredentials` | LDAP user authentication failed (wrong password) | +| `LdapUserNotFound` | User not found in the LDAP directory | +| `LdapMissingMsisdnAttribute` | The configured MSISDN attribute is missing for the user | +| `LdapMissingSerialNrAttribute` | The configured serial number attribute is missing for the user | +| `LdapInvalidMsisdn` | The MSISDN value from LDAP is not a valid phone number | +| `LdapInvalidSerialNumber` | The serial number value from LDAP is invalid | +| `LdapMissingPassword` | The user's password attribute is missing in LDAP | +| `LdapNoReachableHost` | No LDAP host is reachable (all configured hosts failed) | +| `LdapGeofencingGroupMissing` | User is not a member of any geofencing LDAP group | +| `LdapCheckUserAccountControlFailed` | Active Directory User Account Control check failed | +| `LdapNoClassMatchingWithGroupDn` | No Class attribute mapping found for the user's LDAP groups | + +#### RIG Errors + +| Error Code | Description | +|------------|-------------| +| `RigMissingCustomerConfiguration` | No matching customer configuration found for the incoming request | +| `RigOtpMaxAllowedLoginAttemptsExeeded` | Maximum OTP login attempts exceeded | +| `RigOtpNotStored` | OTP session data not found (session may have expired) | +| `RigOtpMismatch` | The OTP entered by the user does not match | +| `RigNoMfaMethodFound` | No valid MFA method found for the user (method not available or not allowed by configuration) | +| `RigLocationValidationFailed` | The user's country code is not allowed by geofencing rules | +| `RigLocationDeviceConfidenceTooLow` | The device confidence score is below the configured threshold | +| `RigLocationLocationConfidenceTooLow` | The location confidence score is below the configured threshold | +| `RigGeofencingConfigError` | Geofencing configuration error | +| `RigOtpInvalidMsisdn` | No valid MSISDN could be extracted from the User-Name value | +| `RigInvalidMsisdn` | The MSISDN is invalid | +| `RigSerialNumberMismatch` | The serial number from the signature response does not match the LDAP value | +| `RigInvalidSerialNumber` | The serial number is invalid | +| `RigInvalidCustomerConfig` | The customer configuration is invalid | +| `FortinetGroupNotFound` | No matching Fortinet group found for the user | + +#### Geofencing-Specific Codes + +| Error Code | Description | +|------------|-------------| +| `MidGeo_100` | Geofencing toggle not enabled in the Mobile ID App | +| `MidGeo_101` | Failed to retrieve user location (resources/timeout) | +| `MidGeo_102` | User has not responded to the location permission dialog | +| `MidGeo_103` | User has denied location access | +| `MidGeo_104` | Location services restricted (parental controls, corporate policy) | +| `MidGeo_105` | Location services turned off device-wide | +| `MidGeo_106` | Location unavailable (airplane mode) | +| `MidGeo_120` | Location failed for an unspecified reason | +| `MidGeo_122` | Application Provider not authorized for geofencing | +| `MidGeo_123` | User has a non-Swisscom SIM card | +| `MidGeo_200` | No location returned from mobile app | +| `MidGeo_201` | App outdated, geofencing not supported | + +## Configuration via Environment Variables + +When using `AppSettings` as the configuration source (single-node deployment without Redis), all customer settings are provided via indexed environment variables. The environment variable names follow the pattern `CustomerConfigs____`. + +### Example + +```bash +# Customer General Configuration +CustomerConfigs__0__Customer=My Company XYZ +CustomerConfigs__0__ApId=mid://ap.mycompany.ch +CustomerConfigs__0__NasIdentifier=ch_mycompany +CustomerConfigs__0__SourceIps__0=10.1.1.22/32 +CustomerConfigs__0__RadiusSharedSecret=MyVeryStrongSharedSecret +CustomerConfigs__0__UseLdap=true +CustomerConfigs__0__DefaultLanguage=en +CustomerConfigs__0__ValidateSerialNr=false +CustomerConfigs__0__UseUserLanguage=true +CustomerConfigs__0__UseUserMfaMethod=true +CustomerConfigs__0__MfaMethods__0=SIM +CustomerConfigs__0__MfaMethods__1=APP +CustomerConfigs__0__MfaMethods__2=OTP +CustomerConfigs__0__MfaMethods__3=NONE + +# LDAP Configuration +CustomerConfigs__0__Ldap__Hosts__Primary=10.0.0.5 +CustomerConfigs__0__Ldap__Hosts__Secondary= +CustomerConfigs__0__Ldap__Hosts__Tertiary= +CustomerConfigs__0__Ldap__Port=389 +CustomerConfigs__0__Ldap__ConnectionTimeoutSeconds=20 +CustomerConfigs__0__Ldap__EnableSsl=false +CustomerConfigs__0__Ldap__AdminUser=cn=admin,dc=mycompany,dc=ch +CustomerConfigs__0__Ldap__AdminPassword=MyAdminPassword +CustomerConfigs__0__Ldap__UseClientCredentialsForConnection=false +CustomerConfigs__0__Ldap__FollowReferrals=false +CustomerConfigs__0__Ldap__DefaultSearchScope=LDAP_SCOPE_SUBTREE +CustomerConfigs__0__Ldap__CheckUserAccountControl=false +CustomerConfigs__0__Ldap__UserSearchBase=ou=users,dc=mycompany,dc=ch +CustomerConfigs__0__Ldap__UserSearchFilter=(&(objectclass=person)(|(sAMAccountName={username})(userPrincipalName={username}))) +CustomerConfigs__0__Ldap__UserGroupSearchFilter=(&(objectClass=groupOfNames)(member={userdn})) +CustomerConfigs__0__Ldap__ValidateUserPassword=true +CustomerConfigs__0__Ldap__MobileNrAttribute=mobile +CustomerConfigs__0__Ldap__LanguageAttribute=preferredLanguage +CustomerConfigs__0__Ldap__SerialNrAttribute=msNPCallingStationID + +# MFA Method Mapping +CustomerConfigs__0__Ldap__MfaMethod__MappingType=Attribute +CustomerConfigs__0__Ldap__MfaMethod__AttributeName=mfa_type +CustomerConfigs__0__Ldap__MfaMethod__Mappings__Sim=LDAP_SIM_VALUE +CustomerConfigs__0__Ldap__MfaMethod__Mappings__App=LDAP_APP_VALUE +CustomerConfigs__0__Ldap__MfaMethod__Mappings__Otp=LDAP_OTP_VALUE +CustomerConfigs__0__Ldap__MfaMethod__Mappings__None=LDAP_NONE_VALUE + +# Geofencing +CustomerConfigs__0__Geofencing__Activate=true +CustomerConfigs__0__Geofencing__Whitelist__0=CH +CustomerConfigs__0__Geofencing__Whitelist__1=DE +CustomerConfigs__0__Geofencing__MinimalDeviceConfidence=0.7 +CustomerConfigs__0__Geofencing__MinimalLocationConfidence=0.7 + +# SIM/APP Display Text +CustomerConfigs__0__SimApp__DisplayText__Default=MobileID: Please Authenticate +CustomerConfigs__0__SimApp__DisplayText__De=MobileID: Bitte mit Mobile ID authentifizieren +CustomerConfigs__0__SimApp__DisplayText__Fr=MobileID: Veuillez vous authentifier avec votre ID mobile +CustomerConfigs__0__SimApp__DisplayText__It=MobileID: Si prega di autenticarsi con il Mobile ID +CustomerConfigs__0__SimApp__DisplayText__En=MobileID: Please authenticate with Mobile ID + +# OTP Configuration +CustomerConfigs__0__Otp__Length=5 +CustomerConfigs__0__Otp__Mode=Text + +# OTP SMS Text ({0} is replaced with the OTP value) +CustomerConfigs__0__Otp__SmsText__Default=Your MobileID code is {0} +CustomerConfigs__0__Otp__SmsText__De=Ihr MobileID Code ist {0} +CustomerConfigs__0__Otp__SmsText__Fr=Le code de votre MobileID est {0} +CustomerConfigs__0__Otp__SmsText__It=Il tuo codice MobileID è {0} +CustomerConfigs__0__Otp__SmsText__En=Your MobileID code is {0} + +CustomerConfigs__0__Otp__ReplyMessageText__Default=Enter the code you have received by SMS +CustomerConfigs__0__Otp__ReplyMessageText__De=Geben Sie den Code ein, den Sie per SMS erhalten haben +CustomerConfigs__0__Otp__ReplyMessageText__Fr=Saisissez le code que vous avez reçu par SMS +CustomerConfigs__0__Otp__ReplyMessageText__It=Inserisci il codice che hai ricevuto via SMS +CustomerConfigs__0__Otp__ReplyMessageText__En=Enter the code you have received by SMS + +# I18N Error Messages (AppSettings mode) +I18nMessages__0__Key=DefaultErrorMessage +I18nMessages__0__De=Authentifizierung fehlgeschlagen +I18nMessages__0__Fr=Échec de l'authentification +I18nMessages__0__It=Autenticazione non riuscita +I18nMessages__0__En=Authentication failed + +I18nMessages__1__Key=Mid_401 +I18nMessages__1__De=Die MobileID-Authentifizierung wurde vom Benutzer abgebrochen. +I18nMessages__1__Fr=L'authentification MobileID a été annulée par l'utilisateur. +I18nMessages__1__It=L'autenticazione MobileID è stata annullata dall'utente. +I18nMessages__1__En=The MobileID authentication was cancelled by the user. + +# Additional customers can be added with incrementing index: +# CustomerConfigs__1__Customer=... +# CustomerConfigs__1__ApId=... +``` + +::: tip Docker Secrets +For sensitive values like certificates and passwords, you can use the `_FILE` suffix convention. Instead of setting the value directly, point to a file: + +```bash +MID_CLIENT_CERTIFICATE_FILE=/run/secrets/mid_certificate +``` + +RIG reads the file content and uses it as the value for `MID_CLIENT_CERTIFICATE`. +::: + +## Multi-Language Support + +All user-facing text messages support four languages: + +| Code | Language | +|------|----------| +| `De` | German | +| `Fr` | French | +| `It` | Italian | +| `En` | English | + +The `Default` key is used as a fallback when the user's language is not available. The user's language is determined by: + +1. The `LanguageAttribute` from LDAP (if `UseUserLanguage` is `true`) +2. The `DefaultLanguage` setting for the customer + +--- + +## RADIUS The RADIUS Protocol + +Source: https://docs.mobileid.ch/radius-interface-gateway-guide/radius-protocol.html + +# The RADIUS Protocol + +## RADIUS Protocol Overview + +The RADIUS protocol, which stands for "Remote Authentication Dial-In User Service," is a network protocol that controls user network access via authentication, authorization, and accounting (AAA or Triple A). It is commonly used for allowing users to access various network devices and services while providing centralized user and permission management. + +The protocol is usually hidden inside controlled network and service access software and is not seen directly by end users. It is used only during the session-establishing part of network traffic. The actual point-to-point communication (the network use that the users are requesting) does not flow through the RADIUS server and is not part of the RADIUS protocol. + +Ease of use and flexibility are the main characteristics of the RADIUS protocol. It can be easily implemented by network devices, access services, and terminal servers while, at the same time, being extended and enriched with custom validation and authentication schemes. The latter feature fits nicely with the scope of this document. + +### Protocol Overview + +The RADIUS protocol is a binary network protocol, operating on ports **1812** and **1813** and running, with respect to the network stack, in the application layer on top of TCP and UDP. The most common implementations of RADIUS use the UDP network protocol, with TCP connections also being supported. + +The protocol is covered by several RFCs, the most important ones being: + +- **[RFC 2865](https://datatracker.ietf.org/doc/html/rfc2865)** — Remote Authentication Dial-In User Service (RADIUS) +- **[RFC 2866](https://datatracker.ietf.org/doc/html/rfc2866)** — RADIUS Accounting +- **[RFC 2869](https://datatracker.ietf.org/doc/html/rfc2869)** — RADIUS Extensions +- **[RFC 6613](https://datatracker.ietf.org/doc/html/rfc6613)** — RADIUS over TCP (updated by [RFC 7930](https://datatracker.ietf.org/doc/html/rfc7930)) + +A larger list of related RFCs can be found in the [Annexes](/radius-interface-gateway-guide/annexes#radius-related-rfcs). + +### Key Concepts + +The following important concepts and terms are used in this document when referring to the RADIUS protocol: + +| Element | Description | +|---------|-------------| +| **User** | The person (or system) that uses a Supplicant to request access to a network service (or other type of service). In the Mobile ID world, this would be a mobile user. | +| **Supplicant** | The software that the User employs to access the network service. The Supplicant collects the credentials from the User and connects to a NAS for requesting access for the User and establishing the service connection. | +| **NAS** | Network Access Server. Although it has "server" in its name, the NAS is the network application/equipment that acts as a client to a RADIUS server. Being asked by the Supplicant to authenticate the User and permit network/service access, the NAS connects to a pre-configured RADIUS server and asks for user authentication and authorization. NAS examples include FTP servers, Web servers, Unix login services, VPN servers, remote desktop servers, etc. | +| **RADIUS Server** | The central server component that decides which Users can access what network services. It is generally one central point in a RADIUS architecture, being connected to all NAS devices that Users can access. | +| **Authentication Session** | A communication between User → Supplicant → NAS and one or more RADIUS server(s) with the scope of permitting access to the User to a network service. The session is always initiated by the User and can result in permission or rejection. | + +Being a binary protocol over UDP, RADIUS packets sent back and forth between the client and the server are composed of bytes with a clearly defined yet flexible structure for representing request or response data. The complete packet structure can be found in RFC 2865, Section 3 — Packet Format. + +For the current document, the important aspects of a RADIUS packet are the fields inside and the values that these fields have: + +- **Code** — Identifies the type of RADIUS packet. While the values are in the range of 1 byte (0–255), for the current document we refer to the respective semantic values: `Access-Request`, `Access-Accept`, `Access-Reject`, `Access-Challenge`. There are more values that can be used for the Code field, corresponding to other packet types, but for the current discussion, these four are the most important ones. +- **Identifier** — Unique number (1 byte) used for matching requests and responses for the same client source IP address and client source UDP port in a short span of time. +- **Authenticator** — (16 bytes) Contains the salt-like vector that is used, together with the shared secret and the user's entered password, to create a unique hash that helps the RADIUS server authenticate the calling client. +- **Attributes** — The attributes of the packet. These depend on the packet type and the service that the user has requested. Logically, they represent the payload of the packet, with the three fields above being the metadata. + +The complete reference for the attributes that a packet can contain is available in RFC 2865, Section 5. + +Since the structure of a packet is a stream of bytes, the attributes must be encoded in a **Type–Length–Value (TLV)** form. For the current discussion and to ease the formatting of packet content, the attributes are represented as a list of name and values, with just the most relevant attributes being included in each snippet. + +Here is a list of attributes used in the next chapters of this document: + +- **User-Name** — The name of the user to be authenticated. It must be sent in Access-Request packets. +- **User-Password** — The password of the user to be authenticated. It is only used in Access-Request packets. +- **Reply-Message** — Indicates a text that may be displayed to the user. It can be used in Access-Accept (the success message), Access-Reject (the failure message), or Access-Challenge (a text to be presented to the user for the challenge). +- **State** — Three or more characters representing a correlation token that must be sent back unchanged when the client needs to send a response to an Access-Challenge request. + +With these fields and attributes defined, here are examples of typical RADIUS packets. + +An **Access-Request** packet: + +``` +Code: Access-Request +Identifier: 10 +Authenticator: A23B55123DB54103 +Attributes: + - NAS-Identifier: digitec-vpn + - User-Name: john + - User-Password: md5("secret"+Authenticator) +``` + +A subsequent **Access-Accept** packet: + +``` +Code: Access-Accept +Identifier: 10 +Authenticator: b4a88417b3d0170d754c647c30b7216a +Attributes: + - Login-Service: Telnet + - Login-TCP-Port: 8080 + - Reply-Message: Authentication successful! +``` + +And, finally, an **Access-Reject** packet: + +``` +Code: Access-Reject +Identifier: 10 +Authenticator: b4a88417b3d0170d754c647c30b7216a +Attributes: + - Reply-Message: Invalid credentials! +``` + +### Basic Flow Description + +A typical RADIUS authentication session is initiated by the user, requesting a specific service to a device or software that is installed on, or accessible from, the user's machine. Such software, called the **Supplicant**, collects the credentials of the user (username and password; these might also be stored for future use, so that the user does not need to enter them each time) and sends them via its own protocol to a **Network Access Server (NAS)** component, capable of providing the requested service. This NAS component is configured to use RADIUS for user authentication, so it creates a RADIUS Access-Request packet, containing the following: + +- The user credentials (User-Name, User-Password) +- An encrypted form of the shared secret between it and the destination RADIUS server +- The NAS client IP and port +- The service type that the user requested +- Any additional attributes that might be needed for proper user authorization + +The diagram below presents this exchange: + +RADIUS basic flow + +The configured RADIUS server receives the packet and proceeds to check the validity of the data and authenticate the user. At this point, the behavior depends on the configuration of the RADIUS server and the process that is required for authenticating and authorizing the user. The RADIUS server might contact other servers to complete the authentication and authorization process and decide on a positive (accept) or negative (reject) response. + +In the diagram above, the RADIUS server decided to inform the NAS client that the user's request is OK and that the requested service can be provided. For this, the RADIUS server sends back a RADIUS packet with code 2 (`Access-Accept`). Should it decide to reject the user's request, the RADIUS server would send back to the NAS client a packet with code 3 (`Access-Reject`). + +As the final step in our flow, the NAS client receives the response packet from the RADIUS server and, if it has an `Access-Accept` code, it moves on to providing the requested service (e.g. establishing a VPN connection). + +### Challenge and Response + +Based on the configuration for a user and during an authentication session, the RADIUS server can decide to perform a challenge/response authentication. This flow introduces a few more steps in the standard RADIUS flow: + +1. After the RADIUS server receives the first RADIUS Access-Request, it sends back to the RADIUS client an **Access-Challenge** response (instead of an Access-Accept or Access-Reject). The response packet contains a challenge code that the user is expected to enter in a security device (smart card or software application) and obtain a response. +2. The RADIUS client receives the Access-Challenge response and uses its custom protocol with the Supplicant application to transfer this challenge and present it to the user. +3. The Supplicant application (e.g. VPN client application) displays the challenge to the user and instructs him/her to enter the challenge code into the security device, calculate the response code, and enter that code back in the UI. +4. The user performs the computation and enters the code back. +5. The Supplicant application sends the response code back to the RADIUS client which, in turn, creates a new RADIUS Access-Request packet, this time with the User-Password field set to the challenge response. +6. The RADIUS server identifies the ongoing authentication session, checks the challenge response, and decides whether to accept the request or not. Depending on the decision, the RADIUS server sends back either an `Access-Accept` (request accepted), an `Access-Reject` (request rejected), or another `Access-Challenge` (more challenge round trips are required). +7. Finally, the Supplicant application and the RADIUS client act together based on the response from the RADIUS server: either give the user access to the service, reject the user, or challenge further. + +The diagram below depicts the Challenge/Response flow: + +RADIUS Challenge and Response flow + +The goal of the RADIUS Challenge/Response flow is to increase the strength of the authentication process by using a two-factor authentication: User-Name + User-Password (something the user knows) and the challenge code calculation (something the user has — the security device). + +### RADIUS via Proxies + +The RADIUS protocol allows network architectures where certain RADIUS server components act as proxies between a RADIUS client and a remote (final) RADIUS server. Whether this is for roaming/federation purposes or for enhancing an authentication session with input from more than one RADIUS server, using RADIUS proxies is an easy and transparent way of assembling a custom authentication flow: + +1. The authentication session starts as usual, with the user requesting a particular service to a Supplicant application. The request is sent via a specific protocol to the backend service that acts as a RADIUS client in this case. +2. The RADIUS client assembles an Access-Request packet and sends it to the configured RADIUS server. +3. Based on the configuration for this RADIUS client or user, the RADIUS server decides to proxy the request, so it sends the Access-Request to the next RADIUS server. For the diagram below, this server is again a proxy, so this step is repeated once more. +4. The Access-Request packet finally lands on the remote RADIUS server. After the due security checks and authorizations, the remote RADIUS server can issue any of an Access-Accept, Access-Reject, or Access-Challenge. +5. The response travels back, from service to service, in reverse order, until it reaches the RADIUS client. At this point, the client acts based on the received response type (accepts or rejects the service or takes the user through a challenge). + +The following diagram depicts this scenario: + +RADIUS via Proxies + +The Proxy scenario is a good asset for assembling a RADIUS-based network. It allows administrators to change the topology of the network without affecting existing RADIUS clients (e.g. VPN server endpoints), existing applications installed on users' machines, or the users' current behavior. + +--- + +## RADIUS Annexes + +Source: https://docs.mobileid.ch/radius-interface-gateway-guide/annexes.html + +# Annexes + +## RADIUS-related RFCs + +The following list contains a set of RFCs that cover the various aspects of the RADIUS protocol and that will come in handy for implementing the solution outlined in this document: + +| RFC | Title | +|-----|-------| +| [RFC 2865](https://datatracker.ietf.org/doc/html/rfc2865) | Remote Authentication Dial-In User Service (RADIUS) | +| [RFC 2866](https://datatracker.ietf.org/doc/html/rfc2866) | RADIUS Accounting | +| [RFC 2867](https://datatracker.ietf.org/doc/html/rfc2867) | RADIUS Accounting Modifications for Tunnel Protocol Support | +| [RFC 2868](https://datatracker.ietf.org/doc/html/rfc2868) | RADIUS Attributes for Tunnel Protocol Support | +| [RFC 2869](https://datatracker.ietf.org/doc/html/rfc2869) | RADIUS Extensions | +| [RFC 3162](https://datatracker.ietf.org/doc/html/rfc3162) | RADIUS and IPv6 | +| [RFC 3575](https://datatracker.ietf.org/doc/html/rfc3575) | IANA Considerations for RADIUS | +| [RFC 3579](https://datatracker.ietf.org/doc/html/rfc3579) | RADIUS Support for Extensible Authentication Protocol | +| [RFC 3580](https://datatracker.ietf.org/doc/html/rfc3580) | IEEE 802.1X RADIUS Usage Guidelines | +| [RFC 5080](https://datatracker.ietf.org/doc/html/rfc5080) | Common RADIUS Implementation Issues and Suggested Fixes | +| [RFC 6158](https://datatracker.ietf.org/doc/html/rfc6158) | RADIUS Design Guidelines | +| [RFC 6572](https://datatracker.ietf.org/doc/html/rfc6572) | RADIUS Support for Proxy Mobile IPv6 | +| [RFC 6613](https://datatracker.ietf.org/doc/html/rfc6613) | RADIUS over TCP (updated by [RFC 7930](https://datatracker.ietf.org/doc/html/rfc7930)) | +| [RFC 6614](https://datatracker.ietf.org/doc/html/rfc6614) | Transport Layer Security (TLS) Encryption for RADIUS | +| [RFC 6929](https://datatracker.ietf.org/doc/html/rfc6929) | RADIUS Protocol Extensions | +| [RFC 7268](https://datatracker.ietf.org/doc/html/rfc7268) | RADIUS Attributes for IEEE 802 Networks | +| [RFC 7930](https://datatracker.ietf.org/doc/html/rfc7930) | Larger Packets for RADIUS over TCP | +| [RFC 8044](https://datatracker.ietf.org/doc/html/rfc8044) | Data Types in RADIUS | +| [RFC 2607](https://datatracker.ietf.org/doc/html/rfc2607) | Proxy Chaining and Policy Implementation in Roaming | + +## RADIUS Testing Tools + +For testing a running instance of the RIG service (or any other RADIUS server), the following tools can be used. + +### Radclient + +The Radclient is a small RADIUS client program that can be used from the command line to send RADIUS packets and print the received responses. Input data can be given via program arguments or with a local configuration file. + +It can be used like this: + +```bash +echo "User-Name = test" | /usr/local/bin/radclient localhost:1812 auth s3cr3t +``` + +```bash +echo "User-Name=test,User-Password=mypass,Framed-Protocol=PPP" | \ + /usr/local/bin/radclient localhost:1812 auth s3cr3t +``` + +```bash +echo "Message-Authenticator = 0x00" | /usr/local/bin/radclient localhost:1812 auth s3cr3t +``` + +#### Testing a RIG Instance + +The following examples show how to use `radclient` to test a running RIG instance specifically. + +**Without LDAP** — the MSISDN is provided as part of the User-Name: + +```bash + radclient -c 1 -r 1 -x -t 30 auth +``` + +**With LDAP** — the RIG service retrieves the user's mobile number via LDAP: + +```bash +echo "User-Name=,User-Password=,NAS-Identifier=" | \ + radclient -c 1 -r 1 -x -t 30 auth +``` + +**OTP (SMS) challenge-response** — if the authentication falls back to OTP via SMS, you will receive an `Access-Challenge` response that includes a `State` value. You must respond with another `Access-Request` that includes the OTP as `User-Password` and the retrieved `State` value: + +```bash + radclient -c 1 -r 1 -x -t 30 auth +``` + +### RADIUS Online Test + +The idBlender company provides a free online web application that functions as a RADIUS client. It uses a backend service to perform the actual RADIUS request (so it is not the browser that sends the RADIUS requests, but a backend service) and can be used to test publicly available RADIUS servers. + +Here is a screenshot from the application: + +RADIUS test online application + +### NTRadPing Test Utility + +The NTRadPing application is a Windows desktop application that can be used for testing a RADIUS server. Since it runs from a local machine, it can easily test any internal/private RADIUS service. + +Here is a screenshot from the application: + +NTRadPing Test Utility + +### Other Tools + +There are other tools that could come in handy during the development and testing phases of the RIG service. For example, the **Simple Radius Test Tool** is an ad-supported Android application that functions as a RADIUS client, and **RadPerf** is a load testing tool for RADIUS servers. + +--- + +## Release Notes Mobile ID Passkeys Launch (2026-03-30) + +Source: https://docs.mobileid.ch/release-notes/posts/2026-03-30-mobile-id-passkeys.html + + + + +Microsoft blocks roughly 7,000 password attacks per second every day, and 47% of consumers abandon a purchase when they forget their password. In a world where phishing remains the most common attack vector, a fundamentally new answer is needed. Passkeys are that answer. Mobile ID now integrates them natively into its OIDC ecosystem and combines them with the proven strengths of SIM and App. + + Mobile ID Passkeys: ecosystem overview with centralized Passkey management and OIDC integration + +## NIST AAL: The Reference Framework for Security Levels + +Before examining each method in detail, a shared understanding of security levels is essential. The NIST standard SP 800-63B defines three Authenticator Assurance Levels (AAL), which serve as the reference framework in regulated industries such as banking, healthcare and government. + +**AAL1** requires only single-factor authentication. Passwords, SMS OTPs or simple tokens satisfy this level. The security level is low. + +**AAL2** requires two different factors. In addition, a phishing-resistant option must be offered for online services. Cloud-synced Passkeys, TOTP generators, Mobile Push (such as Mobile ID SIM or App) and multi-factor OTP devices meet AAL2. + +**AAL3** is the highest level. It requires public-key cryptography, a hardware module validated to FIPS 140 Level 2 or higher, phishing-resistant methods and a non-exportable private key. Re-authentication after 15 minutes of inactivity is also required. Only a few authenticators fully meet these requirements: FIPS-certified security keys (e.g. YubiKey 5 FIPS Series), certain smartcards and hardware security modules. + +## What Are Passkeys? + +Passkeys are a user-friendly implementation of the FIDO2 standard and the WebAuthn API. They replace passwords with cryptographic key pairs and enable login via biometrics in under 3 seconds. The core principle: the private key never leaves the user's device. Instead, the authenticator signs a challenge that the server verifies with the public key. + +What makes Passkeys special is origin binding: the key is cryptographically bound to the domain of the service. Even if a user lands on a perfectly replicated phishing site, authentication fails because the browser detects the wrong domain and refuses to release the key. + +## Passkey Types: Convenience vs. Maximum Security + +Not all Passkeys are created equal. Different types are used depending on the level of protection required. The choice directly affects the achievable security level. + +### Cloud-Synced Passkeys + +Cloud-synced Passkeys are synchronized via the platform provider's cloud infrastructure: Apple iCloud Keychain, Google Password Manager or third-party managers such as 1Password. In mainstream consumer ecosystems, cloud synchronization has become the default user experience because it maximizes recovery and cross-device convenience. + +The major advantage: Passkeys are available across all devices within the same ecosystem. If a device is lost, access is retained through other devices. Synchronization uses end-to-end encryption. Cloud-synced Passkeys can also be shared with family members or friends, which also means they can end up on untrusted devices. + +Security level: **AAL2**. Since the keys are exportable and reside in cloud infrastructures (which are subject to the US CLOUD Act), they do not meet the requirements for AAL3. + +### Device-Bound Passkeys + +With device-bound Passkeys, the private key never leaves the security hardware. Typical examples are FIPS-certified security keys such as the YubiKey 5 FIPS Series (FIPS 140-2 Cert #3907, approx. CHF 100 at Digitec). These offer the highest security and are AAL3-compliant. + +Important to know: standard YubiKeys (without FIPS certification) are not sufficient for AAL3. In September 2024, a severe vulnerability was also discovered in the YubiKey 5 Series that cannot be fixed via firmware update but requires a physical replacement of the token. This illustrates a fundamental problem with physical tokens: security flaws can be expensive and cumbersome to resolve. + +Security level: **AAL3** (only with FIPS 140-2 certification and firmware 5.7 or newer). + +### Platform Authenticators + +Platform authenticators are security modules built directly into the device, such as Windows Hello (TPM), Apple Touch ID/Face ID (Secure Enclave) or the Titan M2 chip in Google Pixel devices. Depending on configuration, they can function as cloud-synced or device-bound. + +AAL3 is only achievable if the key is not synchronized to the cloud and the hardware component is FIPS-validated. In practice, this requires a device-bound configuration or an external authenticator that keeps the private key outside a cloud-synced credential store. + +### 3rd-Party Passkey Providers + +Since iOS 17 and Android 14, third-party providers can register as Passkey providers. The Credential Manager API (Android) and AuthenticationServices (iOS) allow authentication apps to create and manage Passkeys without relying on the system's built-in Passkey store. + +This is the technical foundation for the planned Mobile ID Passkey Vault: the Mobile ID App itself becomes a Passkey provider and can manage device-bound Passkeys at AAL3 level, without requiring physical hardware tokens. + + Passkey types compared by security level: Cloud-Synced, Device-Bound and Platform Authenticators + + +## Passkey Integration: Simple for Users, Complex for Enterprises + +Passkeys promise a simple user experience. The technical reality behind the scenes, however, is demanding. A complete Passkey infrastructure requires: + +A **WebAuthn backend** with FIDO2 server library, attestation validation, credential management and secure key storage. A **credential lifecycle management** system for registration, deactivation, recovery and managing multiple Passkeys per user. **Fallback mechanisms** for users without a Passkey-capable device or when authentication fails. **Compliance checks** for regulated industries, including AAGUID validation against the FIDO Metadata Service (MDS) database and FIPS certification verification. + +Mobile ID resolves this complexity: Relying Parties do not integrate the Passkey infrastructure themselves but rather the Mobile ID OIDC Service. Passkey registration and management takes place centrally on mobileid.ch. A Passkey is registered once and can then be used across all connected Relying Parties. + +For enterprises, this means a standard OIDC integration with configurable ACR values, automatic fallback to SIM, App or SMS, and the assurance of a partner like Swisscom that uses these solutions itself to protect highly critical infrastructures. + +## Security Profile by Usage Context + +All Mobile ID methods provide strong authentication. The optimal choice depends on the use case scenario. The key distinction: is this an open browser scenario with a freely chosen URL, or a closed journey? + +### Browser Journeys: Open URLs and Phishing Risk + +In the browser, the user navigates freely. They can click links in emails, type URLs manually or reach pages via search engines. This is where phishing risk is greatest: attackers can spoof domains and replicate login pages with near-perfect accuracy. + +Passkeys offer a systemic advantage in this scenario. Through cryptographic origin binding, the key is firmly tied to the authentic domain. The browser automatically checks whether the requesting domain matches the registered one. A phishing site on `m0bileid.ch` cannot access a Passkey registered for `mobileid.ch`. This makes Passkeys the first choice for pure web logins. + +Important: Passkeys are not free from attack vectors either. Malware on the platform, compromised browser extensions or social engineering at the operating system level can affect any method. Passkeys specifically eliminate the URL spoofing problem. + +### Closed Journeys: VPN, Remote Desktop, Kiosk, Native Apps + +For logins via VPN clients, remote desktop/VDI environments, kiosk terminals, native app-to-app transitions or helpdesk callbacks, other protection mechanisms apply. In these scenarios there is no freely chosen URL. The connection is controlled by the client or the infrastructure. URL spoofing is not an attack vector. + +Mobile ID SIM and App provide strong security here through hardware binding (EAL5+), geofencing, number matching and transaction signing. Passkeys are often not usable in many of these scenarios: WebAuthn is a browser technology, and VPN clients or remote desktop sessions (no BLE channel to the authenticator!) frequently do not support them. + +### SIM and App Also Usable in the Browser + +SIM and App can also be used for browser logins. Not every use case requires maximum phishing resistance in the browser. For many applications, the proven push-based authentication via SIM or App is a pragmatic and secure solution. Mobile ID covers all scenarios with OIDC and REST API. + + Authentication methods overview: Passkeys, SIM and App compared across scenarios + +## Why SIM and App Remain Indispensable + +Passkeys are a strong addition for browser scenarios. SIM and App leverage their unique strengths where WebAuthn reaches its limits. + +### Mobile ID SIM + +The SIM-based method uses the Mobile ID enabled SIM card (or eSIM) as a secure hardware token. Over 6 million Swiss SIM cards from Swisscom, Sunrise, UPC and Salt are Mobile ID enabled. The cryptographic keys are stored directly on the SIM, which is certified under the protection profile **EAL5+** (ISO/IEC 15408) and Evaluation Level E3 (ITSEC). + +The SIM method requires no app installation and has no app store dependency. The authentication prompt is displayed as a SIM Toolkit overlay directly on top of the business application. It works on any mobile device, including devices without a smartphone operating system, and over the GSM channel. Via SMS-over-IP and WiFi, the SIM method is also usable when there is no cellular connection. + +When switching devices, the user simply moves the SIM. The account remains intact, without re-registration. SIM-based location verification is particularly trustworthy because the position within the mobile network is difficult to manipulate. + +### Mobile ID App + +The Mobile ID App (iOS and Android) offers, alongside biometric authentication, a broad range of additional capabilities that cannot be replicated with Passkeys: + +**Push-based authentication** with biometrics or passcode as the second factor. **Geofencing** with GPS-based location determination and built-in jailbreak and mock service detection, making GPS spoofing more difficult. **Number matching**, where the user confirms a number displayed on screen within the app. **Transaction signing**, which displays transaction details (e.g. "Confirm the transfer of CHF 1,000 to account XY") directly on the device and requires the user's explicit consent. App-to-app transitions enable automated switching between the business application and the Mobile ID App and back in banking scenarios. + +The app is based on technology from Futurae (ETH Zurich spin-off) and uses the device's Trusted Execution Environment (TEE). It is available worldwide in approved countries via the App Store. + +## Passkeys-Plus: The Hybrid Auth Flow for Near AAL3 + +NIST AAL3 is an extremely high security standard. True AAL3 requires, among other things, a FIPS 140-2 validated hardware module, which depends on the specific device configuration. For highly critical systems, Swisscom already uses the **Passkeys-Plus** model internally, which targets a very high security level. + +The approach combines two already existing components into a Hybrid Auth Flow: + +**Step 1: Cloud-Sync Passkey (AAL2).** The user authenticates in the browser with a Passkey. This provides broad ecosystem support and phishing-resistant origin binding. + +**Step 2: Mobile ID Push Step-Up.** The user then receives a push notification on their smartphone. Mobile ID Push uses public-key cryptography with non-exportable, device-bound keys. The user confirms with biometrics or passcode. Geoblocking and user consent display are optionally added. + +The combination delivers: origin-bound login plus device-bound, non-exportable key plus explicit user consent plus geolocation. This can reach AAL3 in deployments where the second factor runs on suitable FIPS 140-2 certified hardware. Whether it is recognized as full AAL3 in every regulatory context must still be assessed per use case, hardware basis and compliance framework. Broader FIPS-validated cryptography and device attestation coverage in the Mobile ID Push step will only be fully available after future enhancements. + +The push step remains on the smartphone. On desktop, the user authenticates locally with the Passkey, and the step-up occurs out-of-band via the phone. + + Hybrid authentication for NIST AAL3: Cloud-Sync Passkey combined with Mobile ID Push Step-Up + + +## Mobile ID Authentication Levels: Granular Control via ACR Values + +Alongside the NIST AAL framework described above, Mobile ID defines its own Authentication Levels (AL2–AL4) as ACR values in the OIDC Authorization Request. These levels control which authentication methods are permitted for a given login and should not be confused with NIST AAL1–AAL3. The full ACR matrix is documented in the [OIDC Integration Guide](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr). + + +In `mid_al4_passkey` mode, a Passkey-only authentication is enforced, guaranteeing true phishing resistance without weak fallbacks. For maximum flexibility, `mid_al2_any` allows all available methods including SMS. With `mid_al4_any`, Passkey authentication is preferred with a fallback to SIM or App. + +While most providers offer Passkeys only as a simple password replacement with insecure recovery paths (Google, PayPal, GitHub and even SBB allow OTP email as a fallback), Mobile ID enables the enforcement of strict security policies and the restriction to FIPS-certified authenticators via AAGUID validation against the FIDO Metadata Service database. + +## Registration and Login Flows + +The technical rollout is straightforward for Relying Parties. + +### Centralized Registration on mobileid.ch + +Users manage their Passkeys via the MyMobileID Dashboard on mobileid.ch/login. There they can add new keys, edit existing ones or delete them. The Passkeys are stored on the domain m.mobileid.ch and are subsequently available across all connected Relying Parties. + +The registration process: + + +

1. Login on mobileid.ch (verification via SMS OTP to confirm the mobile number).

+

2. Select the "Mobile ID Passkey" tile on the dashboard and click "MANAGE PASSKEYS".

+

3. Select "Add a passkey". The native browser dialog appears (Touch ID, Face ID or Security Key).

+

4. Biometric confirmation or PIN entry on the authenticator.

+
+ + +

5. The Passkey is registered and receives a unique KeyRingID.

+

The KeyRingID (e.g. MIDPK5VQ8JV1TGL) is the stable identifier of a Passkey registration. For high-assurance scenarios (AL4), the Relying Party must pass this KeyRingID in the login_hint so that Mobile ID can verify the correct Passkey binding.

+
+ + +

In Passkey management, the user sees all registered Passkeys with type labels: device-bound keys show a star badge, cloud-synced keys show "Synced" and "StepUp" badges. Each entry displays the KeyRingID, the creation date and the last usage.

+
+ + +### RP Login via OIDC + +When a user clicks "Sign in with Mobile ID" at a Relying Party, an OIDC Authorization Code Flow takes place: + + +

1. The RP redirects the user to Mobile ID, with the desired ACR value in the Authorization Request.

+

2. Mobile ID displays the Passkey authentication page ("Passkey or FIDO2 Security Key").

+

3. The native browser dialog appears: "Sign in to mobileid.ch with your passkey".

+

4. The user confirms via biometrics or security key.

+

5. Mobile ID validates the assertion and redirects back to the RP with an authorization code.

+

6. The RP exchanges the code for an ID token and access token.

+
+ +Depending on the configured ACR value, the appropriate flow is triggered. With `mid_al4_passkey`, only a Passkey is accepted. With `mid_al2_any`, the user can choose between Passkey, SIM, App or SMS. In case of errors or missing Passkeys, the RP can allow a secure fallback to other methods. + + +## Roadmap: The Mobile ID Passkey Vault + +With the Mobile ID Passkey Vault, Mobile ID has a roadmap solution in development that is designed to enable AAL3 with the Mobile ID App. The aim is an authenticator that meets the stringent AAL3 requirements and operates on the same security level as a FIPS-certified hardware key, while remaining fully integrated into the Mobile ID ecosystem. + +Compared with physical hardware keys, the Passkey Vault offers clear operational advantages: passkey login can be combined directly with geoblocking and explicit user consent, and the authenticator can be rolled out and scaled far more easily and cost-effectively than expensive hardware tokens. + +The Mobile ID App thus evolves into a scalable software authenticator that unites SIM authentication, push-based MFA, passkey capabilities and transaction signing in a single application. + +## Conclusion: Everything from a Single Source + +With the introduction of Passkeys, Mobile ID solidifies its position as a unique ecosystem that unites all relevant authentication methods under one roof. Passkeys for phishing-resistant browser logins. SIM for the highest hardware security without app installation. App for geofencing, transaction signing and worldwide usability. And with the Hybrid Auth Flow, a solution that achieves near AAL3 level without every user needing to own a hardware token. + +Enterprises benefit from a standard OIDC integration, Swiss data residency and the assurance of a partner that uses these solutions itself to protect highly critical infrastructures. + +**The customer decides which method best fits their use case. Mobile ID provides the flexibility to make it happen.** + +*Mobile ID: the right method for every scenario. Everything from one ecosystem.* + +If you would like to discuss your use case, contact us via [swisscom.ch/mobileid](https://www.swisscom.ch/mobileid). + +--- diff --git a/docs/public/llms.txt b/docs/public/llms.txt index f726678..f92bbe3 100644 --- a/docs/public/llms.txt +++ b/docs/public/llms.txt @@ -94,6 +94,9 @@ - RIG Deployment https://docs.mobileid.ch/radius-interface-gateway-guide/deployment.html +- Configuration + https://docs.mobileid.ch/radius-interface-gateway-guide/configuration.html + - The RADIUS Protocol https://docs.mobileid.ch/radius-interface-gateway-guide/radius-protocol.html @@ -101,6 +104,15 @@ https://docs.mobileid.ch/radius-interface-gateway-guide/annexes.html +## Release Notes + +- Release Notes Overview + https://docs.mobileid.ch/release-notes/ + +- Mobile ID Passkeys Launch (2026-03-30) + https://docs.mobileid.ch/release-notes/posts/2026-03-30-mobile-id-passkeys.html + + ## Additional resources - API Specification (OpenAPI / REST) diff --git a/docs/public/release-notes/fonts/Lato-Bold.woff2 b/docs/public/release-notes/fonts/Lato-Bold.woff2 new file mode 100644 index 0000000..2c8aaa8 Binary files /dev/null and b/docs/public/release-notes/fonts/Lato-Bold.woff2 differ diff --git a/docs/public/release-notes/fonts/Merriweather-Bold.woff2 b/docs/public/release-notes/fonts/Merriweather-Bold.woff2 new file mode 100644 index 0000000..274dd70 Binary files /dev/null and b/docs/public/release-notes/fonts/Merriweather-Bold.woff2 differ diff --git a/docs/public/release-notes/fonts/Merriweather-Regular.woff2 b/docs/public/release-notes/fonts/Merriweather-Regular.woff2 new file mode 100644 index 0000000..45a31ba Binary files /dev/null and b/docs/public/release-notes/fonts/Merriweather-Regular.woff2 differ diff --git a/docs/public/release-notes/img/entra-eam-thumb.png b/docs/public/release-notes/img/entra-eam-thumb.png new file mode 100644 index 0000000..054c8e9 Binary files /dev/null and b/docs/public/release-notes/img/entra-eam-thumb.png differ diff --git a/docs/public/release-notes/img/passkeys-infographic.png b/docs/public/release-notes/img/passkeys-infographic.png new file mode 100644 index 0000000..d95190c Binary files /dev/null and b/docs/public/release-notes/img/passkeys-infographic.png differ diff --git a/docs/public/release-notes/img/passkeys-thumb.png b/docs/public/release-notes/img/passkeys-thumb.png new file mode 100644 index 0000000..23d7ee3 Binary files /dev/null and b/docs/public/release-notes/img/passkeys-thumb.png differ diff --git a/docs/public/release-notes/media/add-a-passkey.png b/docs/public/release-notes/media/add-a-passkey.png new file mode 100644 index 0000000..9060cf3 Binary files /dev/null and b/docs/public/release-notes/media/add-a-passkey.png differ diff --git a/docs/public/release-notes/media/entra-external-mfa-explainer.mp4 b/docs/public/release-notes/media/entra-external-mfa-explainer.mp4 new file mode 100644 index 0000000..1375bd0 Binary files /dev/null and b/docs/public/release-notes/media/entra-external-mfa-explainer.mp4 differ diff --git a/docs/public/release-notes/media/infografik-entra-benefits.jpg b/docs/public/release-notes/media/infografik-entra-benefits.jpg new file mode 100644 index 0000000..438d91a Binary files /dev/null and b/docs/public/release-notes/media/infografik-entra-benefits.jpg differ diff --git a/docs/public/release-notes/media/infografik-entra-integration-flow.jpg b/docs/public/release-notes/media/infografik-entra-integration-flow.jpg new file mode 100644 index 0000000..36fb7b4 Binary files /dev/null and b/docs/public/release-notes/media/infografik-entra-integration-flow.jpg differ diff --git a/docs/public/release-notes/media/infografik-entra-use-cases.jpg b/docs/public/release-notes/media/infografik-entra-use-cases.jpg new file mode 100644 index 0000000..c70d72b Binary files /dev/null and b/docs/public/release-notes/media/infografik-entra-use-cases.jpg differ diff --git a/docs/public/release-notes/media/infografik-flows.webp b/docs/public/release-notes/media/infografik-flows.webp new file mode 100644 index 0000000..6d1d059 Binary files /dev/null and b/docs/public/release-notes/media/infografik-flows.webp differ diff --git a/docs/public/release-notes/media/infografik-hybrid-auth.webp b/docs/public/release-notes/media/infografik-hybrid-auth.webp new file mode 100644 index 0000000..4931925 Binary files /dev/null and b/docs/public/release-notes/media/infografik-hybrid-auth.webp differ diff --git a/docs/public/release-notes/media/infografik-methoden-szenarien.webp b/docs/public/release-notes/media/infografik-methoden-szenarien.webp new file mode 100644 index 0000000..2313570 Binary files /dev/null and b/docs/public/release-notes/media/infografik-methoden-szenarien.webp differ diff --git a/docs/public/release-notes/media/infografik-overview.webp b/docs/public/release-notes/media/infografik-overview.webp new file mode 100644 index 0000000..f080543 Binary files /dev/null and b/docs/public/release-notes/media/infografik-overview.webp differ diff --git a/docs/public/release-notes/media/infografik-passkey-typen.webp b/docs/public/release-notes/media/infografik-passkey-typen.webp new file mode 100644 index 0000000..ea350bd Binary files /dev/null and b/docs/public/release-notes/media/infografik-passkey-typen.webp differ diff --git a/docs/public/release-notes/media/manage-passkeys-2.jpg b/docs/public/release-notes/media/manage-passkeys-2.jpg new file mode 100644 index 0000000..133cf8f Binary files /dev/null and b/docs/public/release-notes/media/manage-passkeys-2.jpg differ diff --git a/docs/public/release-notes/media/manage-passkeys-button.jpg b/docs/public/release-notes/media/manage-passkeys-button.jpg new file mode 100644 index 0000000..98cca6e Binary files /dev/null and b/docs/public/release-notes/media/manage-passkeys-button.jpg differ diff --git a/docs/public/release-notes/media/mymobileid-dashboard-manage-passkeys-tile.png b/docs/public/release-notes/media/mymobileid-dashboard-manage-passkeys-tile.png new file mode 100644 index 0000000..2c1fe43 Binary files /dev/null and b/docs/public/release-notes/media/mymobileid-dashboard-manage-passkeys-tile.png differ diff --git a/docs/public/release-notes/media/passkey-advantage.mp4 b/docs/public/release-notes/media/passkey-advantage.mp4 new file mode 100644 index 0000000..18d54ee Binary files /dev/null and b/docs/public/release-notes/media/passkey-advantage.mp4 differ diff --git a/docs/public/release-notes/media/passkey-check-2.jpg b/docs/public/release-notes/media/passkey-check-2.jpg new file mode 100644 index 0000000..bccf57d Binary files /dev/null and b/docs/public/release-notes/media/passkey-check-2.jpg differ diff --git a/docs/public/release-notes/media/passkey-check-button.jpg b/docs/public/release-notes/media/passkey-check-button.jpg new file mode 100644 index 0000000..990c4b8 Binary files /dev/null and b/docs/public/release-notes/media/passkey-check-button.jpg differ diff --git a/docs/public/release-notes/media/passkey-management-list-passkeys.png b/docs/public/release-notes/media/passkey-management-list-passkeys.png new file mode 100644 index 0000000..71664f6 Binary files /dev/null and b/docs/public/release-notes/media/passkey-management-list-passkeys.png differ diff --git a/docs/public/release-notes/media/sign-in-with-passkey.png b/docs/public/release-notes/media/sign-in-with-passkey.png new file mode 100644 index 0000000..4ea0038 Binary files /dev/null and b/docs/public/release-notes/media/sign-in-with-passkey.png differ diff --git a/docs/radius-interface-gateway-guide/configuration.md b/docs/radius-interface-gateway-guide/configuration.md new file mode 100644 index 0000000..833b4c2 --- /dev/null +++ b/docs/radius-interface-gateway-guide/configuration.md @@ -0,0 +1,819 @@ +# Configuration + +This page describes how to configure the RIG application for your environment. RIG supports two configuration sources: + +| Source | Storage | Best for | +|--------|---------|----------| +| **KeyValueStorage** (Redis) | Customer configs and I18N messages stored as JSON in Redis | Production / multi-node clusters | +| **AppSettings** (Environment Variables) | All configuration provided via environment variables | Single-node deployments without Redis | + +The configuration source is controlled by these environment variables: + +```bash +# Set to 'KeyValueStorage' (Redis) or 'AppSettings' (Environment Variables) +RadiusServer__CustomerConfigSource=KeyValueStorage +RadiusServer__I18nMessagesSource=KeyValueStorage +``` + +## Customer Configuration (Redis) + +When using Redis, add the customer configuration as a JSON string to your Redis database: + +- **Key:** `CUSTOMER_CONFIG_` (e.g., `CUSTOMER_CONFIG_mid://ap.mycompany.ch`) +- **Value:** JSON string (see example below) + +You may configure one or multiple customers. Each customer should have its own Mobile ID account (`ApId`) for separate usage and billing reporting. + +### Request Mapping + +An incoming RADIUS `Access-Request` packet is mapped to the correct customer configuration as follows: + +1. RIG first tries to match the packet's **source IP address** against any `SourceIps` entries in the customer configurations. +2. If no source IP matches, RIG tries to match the inbound `NAS-Identifier` attribute against the `NasIdentifier` entries. + +Ensure each customer configuration has either unique `SourceIps` entries or a unique `NasIdentifier` entry. + +### Customer Configuration Example + +```json +{ + "Customer": "My Company XYZ", + "ApId": "mid://ap.mycompany.ch", + "NasIdentifier": "ch_mycompany", + "SourceIps": [ + "10.1.1.22/32" + ], + "RadiusSharedSecret": "MyVeryStrongSharedSecret", + "AccountingWebhook": { + "Url": "https://my-webhook.example.com/accounting", + "HttpMethod": "POST" + }, + "UseLdap": true, + "Ldap": { + "Hosts": { + "Primary": "10.0.0.5", + "Secondary": "", + "Tertiary": "" + }, + "Port": 389, + "ConnectionTimeoutSeconds": 20, + "EnableSsl": false, + "AdminUser": "cn=admin,dc=mycompany,dc=ch", + "AdminPassword": "MyAdminPassword", + "UseClientCredentialsForConnection": false, + "FollowReferrals": false, + "DefaultSearchScope": "LDAP_SCOPE_SUBTREE", + "CheckUserAccountControl": false, + "UserSearchBase": "ou=users,dc=mycompany,dc=ch", + "UserSearchFilter": "(&(objectclass=person)(|(sAMAccountName={username})(userPrincipalName={username})))", + "UserGroupSearchFilter": "(&(objectClass=groupOfNames)(member={userdn}))", + "ValidateUserPassword": true, + "MobileNrAttribute": "mobile", + "LanguageAttribute": "preferredLanguage", + "SerialNrAttribute": "msNPCallingStationID", + "MfaMethod": { + "MappingType": "Attribute", + "AttributeName": "mfa_type", + "Mappings": { + "Sim": "LDAP_SIM_VALUE", + "App": "LDAP_APP_VALUE", + "Otp": "LDAP_OTP_VALUE", + "None": "LDAP_NONE_VALUE" + } + }, + "ClassMatching": { + "ClassMappings": [ + { + "GroupDn": "cn=readers,ou=users,dc=example,dc=org", + "ClassName": "Group Policy A" + }, + { + "GroupDn": "cn=admins,ou=users,dc=example,dc=org", + "ClassName": "Group Policy B" + } + ] + } + }, + "Geofencing": { + "Activate": true, + "Whitelist": ["CH", "DE"], + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7 + }, + "DefaultLanguage": "en", + "ValidateSerialNr": false, + "UseUserLanguage": false, + "UseUserMfaMethod": true, + "MfaMethods": ["SIM", "APP", "OTP", "NONE"], + "Otp": { + "Length": 5, + "Mode": "Text", + "SmsText": { + "Default": "Ihr MobileID Code ist {0}", + "De": "Ihr MobileID Code ist {0}", + "Fr": "Votre MobileID Code est {0}", + "It": "Il MobileID Code è {0}", + "En": "Your MobileID Code is {0}" + }, + "ReplyMessageText": { + "Default": "Geben Sie den Code ein, den Sie per SMS erhalten haben", + "De": "Geben Sie den Code ein, den Sie per SMS erhalten haben", + "Fr": "Saisissez le code que vous avez reçu par SMS", + "It": "Inserisci il codice che hai ricevuto via SMS", + "En": "Enter the code you have received by SMS" + } + }, + "SimApp": { + "DisplayText": { + "Default": "MobileID: Bitte mit Mobile ID authentifizieren", + "De": "MobileID: Bitte mit Mobile ID authentifizieren", + "Fr": "MobileID: Veuillez vous authentifier avec votre ID mobile", + "It": "MobileID: Si prega di autenticarsi con il Mobile ID", + "En": "MobileID: Please authenticate with Mobile ID" + } + }, + "Events": { + "UnusedMidServiceEvent": { + "ExecutionDelayMinutes": 3, + "NotificationIntervalDays": 7, + "AppSmsText": { + "Default": "Please visit https://mobileid.ch/activate and activate the MobileID App", + "De": "Bitte besuchen Sie https://mobileid.ch/activate und aktivieren Sie die MobileID App", + "Fr": "Veuillez visiter https://mobileid.ch/activate et activer l'application MobileID", + "It": "Visita https://mobileid.ch/activate e attiva l'app MobileID", + "En": "Please visit https://mobileid.ch/activate and activate the MobileID App" + }, + "SimSmsText": { + "Default": "Please visit https://mobileid.ch/activate and activate your MobileID SIM card", + "De": "Bitte besuchen Sie https://mobileid.ch/activate und aktivieren Sie Ihre MobileID SIM-Karte", + "Fr": "Veuillez visiter https://mobileid.ch/activate et activer votre carte SIM MobileID", + "It": "Visita https://mobileid.ch/activate e attiva la tua SIM MobileID", + "En": "Please visit https://mobileid.ch/activate and activate your MobileID SIM card" + } + }, + "ErrorNotificationEvent": { + "ExecutionDelayMinutes": 0, + "HandledErrorCodes": [ + { + "ErrorCode": "RigSerialNumberMismatch", + "NotificationIntervalDays": 1, + "SmsText": { + "Default": "Your MobileID Token has changed. Please re-register your MobileID.", + "De": "Ihr MobileID Token hat sich geändert. Bitte registrieren Sie Ihr MobileID erneut.", + "Fr": "Votre jeton MobileID a changé. Veuillez réenregistrer votre MobileID.", + "It": "Il tuo token MobileID è cambiato. Registra nuovamente il tuo MobileID.", + "En": "Your MobileID Token has changed. Please re-register your MobileID." + } + } + ] + } + } +} +``` + +The following sections explain each configuration area in detail. + +## General Settings + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Customer` | string | Display name for the customer | +| `ApId` | string | Mobile ID Application Provider ID (e.g., `mid://ap.mycompany.ch`) | +| `NasIdentifier` | string | RADIUS NAS identifier for matching incoming requests | +| `SourceIps` | string[] | Allowed source IP addresses/ranges in CIDR notation (e.g., `10.1.1.22/32`) | +| `RadiusSharedSecret` | string | RADIUS shared secret for authenticating RADIUS packets | +| `DefaultLanguage` | string | Default language code: `de`, `fr`, `it`, or `en` | +| `ValidateSerialNr` | boolean | Validate user's Mobile ID serial number against LDAP attribute | +| `UseUserLanguage` | boolean | Load the user's language preference from LDAP | +| `UseUserMfaMethod` | boolean | Load the user's preferred MFA method from LDAP | +| `MfaMethods` | string[] | Ordered list of allowed MFA methods: `SIM`, `APP`, `OTP`, `NONE` | +| `UseLdap` | boolean | Enable LDAP integration for user attribute lookup | + +### Accounting Webhook + +Forward RADIUS accounting traffic to an external system: + +```json +"AccountingWebhook": { + "Url": "https://my-webhook.example.com/accounting", + "HttpMethod": "POST" +} +``` + +## LDAP Configuration + +The LDAP section configures how RIG connects to your directory service to retrieve user attributes. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Hosts.Primary` | string | Primary LDAP server hostname or IP address | +| `Hosts.Secondary` | string | Secondary (failover) LDAP server | +| `Hosts.Tertiary` | string | Tertiary (failover) LDAP server | +| `Port` | integer | LDAP port (`389` for LDAP, `636` for LDAPS) | +| `ConnectionTimeoutSeconds` | integer | Connection timeout in seconds | +| `EnableSsl` | boolean | Enable SSL/TLS for LDAP connections | +| `AdminUser` | string | Service account DN for LDAP queries | +| `AdminPassword` | string | Service account password | +| `UseClientCredentialsForConnection` | boolean | Use the RADIUS client's credentials instead of the admin user for LDAP connection | +| `FollowReferrals` | boolean | Follow LDAP referrals | +| `DefaultSearchScope` | string | LDAP search scope (e.g., `LDAP_SCOPE_SUBTREE`) | +| `CheckUserAccountControl` | boolean | Check Active Directory's `userAccountControl` attribute to verify the account is active | +| `UserSearchBase` | string | Base DN for user searches (e.g., `ou=users,dc=mycompany,dc=ch`) | +| `UserSearchFilter` | string | LDAP search filter with placeholders (see below) | +| `UserGroupSearchFilter` | string | LDAP filter for retrieving group memberships | +| `ValidateUserPassword` | boolean | Validate the user's password against LDAP | +| `MobileNrAttribute` | string | LDAP attribute containing the user's phone number (MSISDN) | +| `LanguageAttribute` | string | LDAP attribute for user's preferred language | +| `SerialNrAttribute` | string | LDAP attribute for Mobile ID serial number | + +### Search Filter Placeholders + +The following placeholders can be used in LDAP search filters: + +| Placeholder | Description | +|-------------|-------------| +| `{username}` | The username part from the RADIUS `User-Name` attribute (before `@`) | +| `{domain}` | The domain part from the RADIUS `User-Name` attribute (after `@`) | +| `{userdn}` | The full DN of the user (available after the initial user search) | + +**Example search filters:** + +``` +# Active Directory (sAMAccountName or UPN) +(&(objectclass=person)(|(sAMAccountName={username})(userPrincipalName={username}))) + +# OpenLDAP (uid) +(&(objectclass=inetOrgPerson)(uid={username}{domain})) + +# Group membership search +(&(objectClass=groupOfNames)(member={userdn})) +``` + +## MFA Method Mapping + +The MFA method for each user can be determined in two ways: + +### Option 1: LDAP Attribute Mapping + +Map an LDAP attribute value to an MFA method: + +```json +"MfaMethod": { + "MappingType": "Attribute", + "AttributeName": "mfa_type", + "Mappings": { + "Sim": "LDAP_SIM_VALUE", + "App": "LDAP_APP_VALUE", + "Otp": "LDAP_OTP_VALUE", + "None": "LDAP_NONE_VALUE" + } +} +``` + +Replace the `LDAP_*_VALUE` strings with the actual attribute values used in your LDAP directory. + +### Option 2: LDAP Group DN Mapping + +Map LDAP group membership to an MFA method: + +```json +"MfaMethod": { + "MappingType": "GroupDn", + "Mappings": { + "Sim": "cn=mfa-sim,ou=groups,dc=example,dc=org", + "App": "cn=mfa-app,ou=groups,dc=example,dc=org", + "Otp": "cn=mfa-otp,ou=groups,dc=example,dc=org", + "None": "cn=mfa-none,ou=groups,dc=example,dc=org" + } +} +``` + +## RADIUS Class Attribute Mapping + +The RADIUS `Class` attribute can be included in `Access-Accept` responses based on LDAP group membership. This is useful for applying policies on the RADIUS client side. + +```json +"ClassMatching": { + "ClassMappings": [ + { + "GroupDn": "cn=admins,ou=groups,dc=example,dc=org", + "ClassName": "Admin Policy" + }, + { + "GroupDn": "cn=users,ou=groups,dc=example,dc=org", + "ClassName": "Standard Policy" + } + ] +} +``` + +When a user is a member of a matching LDAP group, the corresponding `ClassName` is included as the `Class` attribute in the RADIUS `Access-Accept` response. + +## Geofencing + +RIG supports geofencing to restrict authentication based on the user's geographic location. There are two modes: **simple** (country whitelist/blacklist) and **LDAP-based** (geofencing rules managed in the directory). + +### Simple Geofencing + +Define a whitelist or blacklist of ISO country codes: + +::: code-group + +```json [Whitelist] +"Geofencing": { + "Activate": true, + "Whitelist": ["CH", "DE", "FR", "IT", "AT"], + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7 +} +``` + +```json [Blacklist] +"Geofencing": { + "Activate": true, + "Blacklist": ["US", "CN", "RU"], + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7 +} +``` + +::: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Activate` | boolean | Enable or disable geofencing | +| `Whitelist` | string[] | ISO country codes that are allowed (mutually exclusive with `Blacklist`) | +| `Blacklist` | string[] | ISO country codes that are blocked (mutually exclusive with `Whitelist`) | +| `MinimalDeviceConfidence` | decimal | Minimum device confidence score (0.0–1.0) | +| `MinimalLocationConfidence` | decimal | Minimum location confidence score (0.0–1.0) | + +::: warning +`Whitelist` and `Blacklist` are mutually exclusive — define one or the other, not both. +::: + +### LDAP-Based Geofencing + +For more granular control, geofencing rules can be managed in the LDAP directory. This allows different whitelist/blacklist rules per user group. + +```json +"Ldap": { + "Geofencing": { + "Activate": true, + "GeofencingSearchBase": "dc=mycompany,dc=ch", + "UserGeoGroupSearchFilter": "(&(objectClass=groupOfNames)(member={userdn})(ou=geo-groups))", + "CountriesSearchFilter": "(objectClass=country)", + "MinimalDeviceConfidence": 0.7, + "MinimalLocationConfidence": 0.7, + "FailAuthIfGroupMissing": true, + "BlacklistGroupPrefix": "blacklist-", + "WhitelistGroupPrefix": "whitelist-" + } +} +``` + +| Parameter | Type | Description | +|-----------|------|-------------| +| `GeofencingSearchBase` | string | Base DN for geofencing group searches | +| `UserGeoGroupSearchFilter` | string | LDAP filter to find the user's geofencing group | +| `CountriesSearchFilter` | string | LDAP filter to find country entries within a group | +| `FailAuthIfGroupMissing` | boolean | Reject authentication if the user is not in any geofencing group | +| `BlacklistGroupPrefix` | string | Prefix for blacklist group names (e.g., `blacklist-`) | +| `WhitelistGroupPrefix` | string | Prefix for whitelist group names (e.g., `whitelist-`) | + +## Fortinet VSA Support + +RIG supports Fortinet Vendor Specific Attributes (VSA) to enrich RADIUS `Access-Accept` responses with Fortinet-specific attributes. This is useful when RIG is used together with FortiGate firewalls. + +The FortiGate behaviour is triggered when: +1. The Vendor Specific Attribute `Fortinet-Vdom-Name` is present in the incoming RADIUS `Access-Request` packet +2. The value of `Fortinet-Vdom-Name` matches the configured `VendorSpecificAttributeTriggerValue` + +### Configuration Example + +Add the `FortigateBehaviour` section inside the `Ldap` configuration: + +```json +"Ldap": { + "UserGroupSearchFilter": "(&(objectClass=groupOfNames)(member={userdn}))", + "FortigateBehaviour": { + "VendorSpecificAttributeTriggerValue": "root", + "FortinetLdapUserGroupMap": [ + { + "ForitnetGroupName": "gu-rad_msrl_sslvpn1", + "LdapGroupDn": "cn=Admin,ou=Groups,dc=example,dc=local" + }, + { + "ForitnetGroupName": "gu-rad_msrl_sslvpn2", + "LdapGroupDn": "cn=Viewer,ou=Groups,dc=example,dc=local" + } + ], + "FortinetAccessProfile": "none", + "DefaultFortinetGroupName": "no-group-found", + "FailAuthIfGroupUnknown": false + } +} +``` + +::: info +The property name `ForitnetGroupName` (note the spelling) is the actual field name used by the application. The LDAP `UserGroupSearchFilter` used for the Fortinet group lookup is defined at the `Ldap` level (not inside `FortigateBehaviour`). +::: + +### Behaviour + +After authenticating the user, RIG reads out all LDAP user groups and matches them against the `FortinetLdapUserGroupMap` entries. The **first matching group** is used. + +**If a matching group is found**, the `Access-Accept` response is enriched with: + +| Attribute | Value | +|-----------|-------| +| `Fortinet-Vdom-Name` | Value from the incoming `Access-Request` (e.g., `root`) | +| `Fortinet-Group-Name` | The matching `ForitnetGroupName` value | +| `Fortinet-Access-Profile` | The configured `FortinetAccessProfile` value | + +**If no matching group is found:** + +- If `FailAuthIfGroupUnknown` is `true`: the authentication is rejected +- If `FailAuthIfGroupUnknown` is `false`: the `Access-Accept` is enriched with the `DefaultFortinetGroupName` + +## OTP Configuration + +Configure the One-Time Password behaviour for SMS-based authentication: + +| Parameter | Type | Description | +|-----------|------|-------------| +| `Length` | integer | Number of digits in the OTP (e.g., `5`) | +| `Mode` | string | OTP mode (`Text`) | +| `SmsText` | object | Multi-language SMS text template. Use `{0}` as placeholder for the OTP value | +| `ReplyMessageText` | object | Multi-language prompt text for the RADIUS `Access-Challenge` response | + +## SIM/APP Display Text + +Configure the text displayed on the user's mobile device during SIM or APP authentication: + +```json +"SimApp": { + "DisplayText": { + "Default": "MobileID: Please authenticate with Mobile ID", + "De": "MobileID: Bitte mit Mobile ID authentifizieren", + "Fr": "MobileID: Veuillez vous authentifier avec votre ID mobile", + "It": "MobileID: Si prega di autenticarsi con il Mobile ID", + "En": "MobileID: Please authenticate with Mobile ID" + } +} +``` + +::: tip +The `DisplayText` value is shown to the user on their mobile device. You can prefix it with your company or application name (e.g., `MyCompany VPN: Please authenticate with Mobile ID`). +::: + +## SMS Event Notifications + +RIG can send SMS notifications to users in specific situations. All event notifications are optional. + +### Unused Mobile ID Service Event + +After a successful authentication that fell back to OTP (because the user has no active Mobile ID SIM or APP), RIG can send an SMS notification to encourage the user to activate their Mobile ID account. + +| Parameter | Type | Description | +|-----------|------|-------------| +| `ExecutionDelayMinutes` | integer | Delay in minutes before sending the notification | +| `NotificationIntervalDays` | integer | Minimum days between notifications to the same user | +| `AppSmsText` | object | Multi-language SMS text when SIM is **not** Mobile ID-compliant (suggest App activation) | +| `SimSmsText` | object | Multi-language SMS text when SIM **is** Mobile ID-compliant (suggest SIM activation) | + +### Error Notification Event + +Send an SMS notification to the user when a specific error occurs during authentication (e.g., serial number mismatch, geofencing error). + +```json +"ErrorNotificationEvent": { + "ExecutionDelayMinutes": 0, + "HandledErrorCodes": [ + { + "ErrorCode": "RigSerialNumberMismatch", + "NotificationIntervalDays": 1, + "SmsText": { + "Default": "Your MobileID Token has changed. Please re-register.", + "De": "Ihr MobileID Token hat sich geändert. Bitte registrieren Sie sich erneut.", + "Fr": "Votre jeton MobileID a changé. Veuillez vous réenregistrer.", + "It": "Il tuo token MobileID è cambiato. Registrati nuovamente.", + "En": "Your MobileID Token has changed. Please re-register." + } + }, + { + "ErrorCode": "MidGeo_100", + "NotificationIntervalDays": 1, + "SmsText": { + "Default": "Please enable the Geofencing toggle in your MobileID App.", + "De": "Bitte aktivieren Sie den Geofencing-Schalter in Ihrer MobileID App.", + "Fr": "Veuillez activer le commutateur de géorepérage dans votre application MobileID.", + "It": "Abilita l'interruttore di geofencing nella tua app MobileID.", + "En": "Please enable the Geofencing toggle in your MobileID App." + } + } + ] +} +``` + +## I18N Error Messages + +The I18N error message configuration allows you to customize the `Reply-Message` content in RADIUS `Access-Reject` responses. Messages are defined per error code in four languages (German, French, Italian, English). + +### Configuration via Redis + +Add the I18N messages as a JSON array to Redis: + +- **Key:** `I18N_MESSAGES` +- **Value:** JSON array (see example below) + +::: info +The RIG application must be restarted after an I18N configuration change in Redis. +::: + +```json +[ + { + "Key": "DefaultErrorMessage", + "De": "Authentifizierung fehlgeschlagen", + "Fr": "Échec de l'authentification", + "It": "Autenticazione non riuscita", + "En": "Authentication failed" + }, + { + "Key": "Mid_105", + "De": "Diese Rufnummer ist keine bekannte MobileID-Nummer.", + "Fr": "Ce numéro de téléphone n'est pas un numéro MobileID connu.", + "It": "Questo numero di telefono non è un numero MobileID conosciuto.", + "En": "This phone number is an unknown MobileID number." + }, + { + "Key": "Mid_208", + "De": "Die MobileID-Sitzung ist abgelaufen. Bitte versuchen Sie es erneut.", + "Fr": "La session MobileID a expiré. Veuillez réessayer.", + "It": "La sessione MobileID è scaduta. Riprova.", + "En": "The MobileID authentication session has expired. Please try again." + }, + { + "Key": "Mid_401", + "De": "Die MobileID-Authentifizierung wurde vom Benutzer abgebrochen.", + "Fr": "L'authentification MobileID a été annulée par l'utilisateur.", + "It": "L'autenticazione MobileID è stata annullata dall'utente.", + "En": "The MobileID authentication was cancelled by the user." + }, + { + "Key": "Mid_402", + "De": "Die MobileID-PIN ist gesperrt. Besuchen Sie https://mobileid.ch/reset um sie zurückzusetzen.", + "Fr": "Le PIN MobileID est bloqué. Visitez https://mobileid.ch/reset pour le réinitialiser.", + "It": "Il PIN MobileID è bloccato. Visita https://mobileid.ch/reset per reimpostarlo.", + "En": "The MobileID PIN is blocked. Please visit https://mobileid.ch/reset to reset it." + }, + { + "Key": "Mid_404", + "De": "Kein aktives MobileID gefunden. Besuchen Sie https://mobileid.ch/activate zur Aktivierung.", + "Fr": "Aucun MobileID actif trouvé. Visitez https://mobileid.ch/activate pour l'activer.", + "It": "Nessun MobileID attivo trovato. Visita https://mobileid.ch/activate per attivarlo.", + "En": "No active MobileID found. Please visit https://mobileid.ch/activate to activate." + }, + { + "Key": "Mid_406", + "De": "Es läuft bereits eine MobileID-Authentifizierung. Bitte warten und erneut versuchen.", + "Fr": "Une authentification MobileID est déjà en cours. Veuillez patienter et réessayer.", + "It": "Un'autenticazione MobileID è già in corso. Attendere e riprovare.", + "En": "There is already a MobileID authentication on-going. Please wait and try again." + }, + { + "Key": "Mid_422", + "De": "Kein aktives MobileID gefunden. Besuchen Sie https://mobileid.ch/activate zur Aktivierung.", + "Fr": "Aucun MobileID actif trouvé. Visitez https://mobileid.ch/activate pour l'activer.", + "It": "Nessun MobileID attivo trovato. Visita https://mobileid.ch/activate per attivarlo.", + "En": "No active MobileID found. Please visit https://mobileid.ch/activate to activate." + }, + { + "Key": "LdapInvalidCredentials", + "De": "LDAP-Authentifizierung fehlgeschlagen. Bitte überprüfen Sie Ihre Zugangsdaten.", + "Fr": "Échec de l'authentification LDAP. Veuillez vérifier vos identifiants.", + "It": "Autenticazione LDAP non riuscita. Verificare le credenziali.", + "En": "LDAP user authentication failed. Please verify your credentials and try again." + }, + { + "Key": "LdapUserNotFound", + "De": "LDAP-Benutzer nicht gefunden. Bitte überprüfen Sie Ihre Zugangsdaten.", + "Fr": "Utilisateur LDAP introuvable. Veuillez vérifier vos identifiants.", + "It": "Utente LDAP non trovato. Verificare le credenziali.", + "En": "LDAP user not found. Please verify your credentials and try again." + }, + { + "Key": "RigOtpMismatch", + "De": "Das eingegebene Einmalpasswort ist ungültig.", + "Fr": "Le mot de passe à usage unique saisi est invalide.", + "It": "La password monouso inserita non è valida.", + "En": "The One-Time-Password entered is invalid." + }, + { + "Key": "RigOtpMaxAllowedLoginAttemptsExeeded", + "De": "Die maximale Anzahl an OTP-Anmeldeversuchen wurde überschritten.", + "Fr": "Le nombre maximum de tentatives de connexion OTP a été dépassé.", + "It": "Il numero massimo di tentativi di accesso OTP è stato superato.", + "En": "The maximum number of OTP login attempts has been exceeded." + }, + { + "Key": "RigLocationValidationFailed", + "De": "Der aktuelle Standort ist nicht erlaubt.", + "Fr": "L'emplacement actuel n'est pas autorisé.", + "It": "La posizione attuale non è consentita.", + "En": "The user's current country code is not allowed." + } +] +``` + +### Supported Error Codes + +The following error codes can be used in both the I18N error message configuration and the error notification events: + +#### Mobile ID Errors + +| Error Code | Description | +|------------|-------------| +| `Mid_{code}` | Any 3-digit Mobile ID API error code (e.g., `Mid_401`, `Mid_404`). Refer to the Mobile ID Client Reference Guide. | +| `MidGeo_{code}` | Any 3-digit Mobile ID Geofencing error code (e.g., `MidGeo_100`). Refer to the Mobile ID Client Reference Guide. | +| `MidInvalidSerialNumber` | The Mobile ID serial number from the signature response is invalid | + +#### LDAP Errors + +| Error Code | Description | +|------------|-------------| +| `LdapInvalidCredentials` | LDAP user authentication failed (wrong password) | +| `LdapUserNotFound` | User not found in the LDAP directory | +| `LdapMissingMsisdnAttribute` | The configured MSISDN attribute is missing for the user | +| `LdapMissingSerialNrAttribute` | The configured serial number attribute is missing for the user | +| `LdapInvalidMsisdn` | The MSISDN value from LDAP is not a valid phone number | +| `LdapInvalidSerialNumber` | The serial number value from LDAP is invalid | +| `LdapMissingPassword` | The user's password attribute is missing in LDAP | +| `LdapNoReachableHost` | No LDAP host is reachable (all configured hosts failed) | +| `LdapGeofencingGroupMissing` | User is not a member of any geofencing LDAP group | +| `LdapCheckUserAccountControlFailed` | Active Directory User Account Control check failed | +| `LdapNoClassMatchingWithGroupDn` | No Class attribute mapping found for the user's LDAP groups | + +#### RIG Errors + +| Error Code | Description | +|------------|-------------| +| `RigMissingCustomerConfiguration` | No matching customer configuration found for the incoming request | +| `RigOtpMaxAllowedLoginAttemptsExeeded` | Maximum OTP login attempts exceeded | +| `RigOtpNotStored` | OTP session data not found (session may have expired) | +| `RigOtpMismatch` | The OTP entered by the user does not match | +| `RigNoMfaMethodFound` | No valid MFA method found for the user (method not available or not allowed by configuration) | +| `RigLocationValidationFailed` | The user's country code is not allowed by geofencing rules | +| `RigLocationDeviceConfidenceTooLow` | The device confidence score is below the configured threshold | +| `RigLocationLocationConfidenceTooLow` | The location confidence score is below the configured threshold | +| `RigGeofencingConfigError` | Geofencing configuration error | +| `RigOtpInvalidMsisdn` | No valid MSISDN could be extracted from the User-Name value | +| `RigInvalidMsisdn` | The MSISDN is invalid | +| `RigSerialNumberMismatch` | The serial number from the signature response does not match the LDAP value | +| `RigInvalidSerialNumber` | The serial number is invalid | +| `RigInvalidCustomerConfig` | The customer configuration is invalid | +| `FortinetGroupNotFound` | No matching Fortinet group found for the user | + +#### Geofencing-Specific Codes + +| Error Code | Description | +|------------|-------------| +| `MidGeo_100` | Geofencing toggle not enabled in the Mobile ID App | +| `MidGeo_101` | Failed to retrieve user location (resources/timeout) | +| `MidGeo_102` | User has not responded to the location permission dialog | +| `MidGeo_103` | User has denied location access | +| `MidGeo_104` | Location services restricted (parental controls, corporate policy) | +| `MidGeo_105` | Location services turned off device-wide | +| `MidGeo_106` | Location unavailable (airplane mode) | +| `MidGeo_120` | Location failed for an unspecified reason | +| `MidGeo_122` | Application Provider not authorized for geofencing | +| `MidGeo_123` | User has a non-Swisscom SIM card | +| `MidGeo_200` | No location returned from mobile app | +| `MidGeo_201` | App outdated, geofencing not supported | + +## Configuration via Environment Variables + +When using `AppSettings` as the configuration source (single-node deployment without Redis), all customer settings are provided via indexed environment variables. The environment variable names follow the pattern `CustomerConfigs____`. + +### Example + +```bash +# Customer General Configuration +CustomerConfigs__0__Customer=My Company XYZ +CustomerConfigs__0__ApId=mid://ap.mycompany.ch +CustomerConfigs__0__NasIdentifier=ch_mycompany +CustomerConfigs__0__SourceIps__0=10.1.1.22/32 +CustomerConfigs__0__RadiusSharedSecret=MyVeryStrongSharedSecret +CustomerConfigs__0__UseLdap=true +CustomerConfigs__0__DefaultLanguage=en +CustomerConfigs__0__ValidateSerialNr=false +CustomerConfigs__0__UseUserLanguage=true +CustomerConfigs__0__UseUserMfaMethod=true +CustomerConfigs__0__MfaMethods__0=SIM +CustomerConfigs__0__MfaMethods__1=APP +CustomerConfigs__0__MfaMethods__2=OTP +CustomerConfigs__0__MfaMethods__3=NONE + +# LDAP Configuration +CustomerConfigs__0__Ldap__Hosts__Primary=10.0.0.5 +CustomerConfigs__0__Ldap__Hosts__Secondary= +CustomerConfigs__0__Ldap__Hosts__Tertiary= +CustomerConfigs__0__Ldap__Port=389 +CustomerConfigs__0__Ldap__ConnectionTimeoutSeconds=20 +CustomerConfigs__0__Ldap__EnableSsl=false +CustomerConfigs__0__Ldap__AdminUser=cn=admin,dc=mycompany,dc=ch +CustomerConfigs__0__Ldap__AdminPassword=MyAdminPassword +CustomerConfigs__0__Ldap__UseClientCredentialsForConnection=false +CustomerConfigs__0__Ldap__FollowReferrals=false +CustomerConfigs__0__Ldap__DefaultSearchScope=LDAP_SCOPE_SUBTREE +CustomerConfigs__0__Ldap__CheckUserAccountControl=false +CustomerConfigs__0__Ldap__UserSearchBase=ou=users,dc=mycompany,dc=ch +CustomerConfigs__0__Ldap__UserSearchFilter=(&(objectclass=person)(|(sAMAccountName={username})(userPrincipalName={username}))) +CustomerConfigs__0__Ldap__UserGroupSearchFilter=(&(objectClass=groupOfNames)(member={userdn})) +CustomerConfigs__0__Ldap__ValidateUserPassword=true +CustomerConfigs__0__Ldap__MobileNrAttribute=mobile +CustomerConfigs__0__Ldap__LanguageAttribute=preferredLanguage +CustomerConfigs__0__Ldap__SerialNrAttribute=msNPCallingStationID + +# MFA Method Mapping +CustomerConfigs__0__Ldap__MfaMethod__MappingType=Attribute +CustomerConfigs__0__Ldap__MfaMethod__AttributeName=mfa_type +CustomerConfigs__0__Ldap__MfaMethod__Mappings__Sim=LDAP_SIM_VALUE +CustomerConfigs__0__Ldap__MfaMethod__Mappings__App=LDAP_APP_VALUE +CustomerConfigs__0__Ldap__MfaMethod__Mappings__Otp=LDAP_OTP_VALUE +CustomerConfigs__0__Ldap__MfaMethod__Mappings__None=LDAP_NONE_VALUE + +# Geofencing +CustomerConfigs__0__Geofencing__Activate=true +CustomerConfigs__0__Geofencing__Whitelist__0=CH +CustomerConfigs__0__Geofencing__Whitelist__1=DE +CustomerConfigs__0__Geofencing__MinimalDeviceConfidence=0.7 +CustomerConfigs__0__Geofencing__MinimalLocationConfidence=0.7 + +# SIM/APP Display Text +CustomerConfigs__0__SimApp__DisplayText__Default=MobileID: Please Authenticate +CustomerConfigs__0__SimApp__DisplayText__De=MobileID: Bitte mit Mobile ID authentifizieren +CustomerConfigs__0__SimApp__DisplayText__Fr=MobileID: Veuillez vous authentifier avec votre ID mobile +CustomerConfigs__0__SimApp__DisplayText__It=MobileID: Si prega di autenticarsi con il Mobile ID +CustomerConfigs__0__SimApp__DisplayText__En=MobileID: Please authenticate with Mobile ID + +# OTP Configuration +CustomerConfigs__0__Otp__Length=5 +CustomerConfigs__0__Otp__Mode=Text + +# OTP SMS Text ({0} is replaced with the OTP value) +CustomerConfigs__0__Otp__SmsText__Default=Your MobileID code is {0} +CustomerConfigs__0__Otp__SmsText__De=Ihr MobileID Code ist {0} +CustomerConfigs__0__Otp__SmsText__Fr=Le code de votre MobileID est {0} +CustomerConfigs__0__Otp__SmsText__It=Il tuo codice MobileID è {0} +CustomerConfigs__0__Otp__SmsText__En=Your MobileID code is {0} + +CustomerConfigs__0__Otp__ReplyMessageText__Default=Enter the code you have received by SMS +CustomerConfigs__0__Otp__ReplyMessageText__De=Geben Sie den Code ein, den Sie per SMS erhalten haben +CustomerConfigs__0__Otp__ReplyMessageText__Fr=Saisissez le code que vous avez reçu par SMS +CustomerConfigs__0__Otp__ReplyMessageText__It=Inserisci il codice che hai ricevuto via SMS +CustomerConfigs__0__Otp__ReplyMessageText__En=Enter the code you have received by SMS + +# I18N Error Messages (AppSettings mode) +I18nMessages__0__Key=DefaultErrorMessage +I18nMessages__0__De=Authentifizierung fehlgeschlagen +I18nMessages__0__Fr=Échec de l'authentification +I18nMessages__0__It=Autenticazione non riuscita +I18nMessages__0__En=Authentication failed + +I18nMessages__1__Key=Mid_401 +I18nMessages__1__De=Die MobileID-Authentifizierung wurde vom Benutzer abgebrochen. +I18nMessages__1__Fr=L'authentification MobileID a été annulée par l'utilisateur. +I18nMessages__1__It=L'autenticazione MobileID è stata annullata dall'utente. +I18nMessages__1__En=The MobileID authentication was cancelled by the user. + +# Additional customers can be added with incrementing index: +# CustomerConfigs__1__Customer=... +# CustomerConfigs__1__ApId=... +``` + +::: tip Docker Secrets +For sensitive values like certificates and passwords, you can use the `_FILE` suffix convention. Instead of setting the value directly, point to a file: + +```bash +MID_CLIENT_CERTIFICATE_FILE=/run/secrets/mid_certificate +``` + +RIG reads the file content and uses it as the value for `MID_CLIENT_CERTIFICATE`. +::: + +## Multi-Language Support + +All user-facing text messages support four languages: + +| Code | Language | +|------|----------| +| `De` | German | +| `Fr` | French | +| `It` | Italian | +| `En` | English | + +The `Default` key is used as a fallback when the user's language is not available. The user's language is determined by: + +1. The `LanguageAttribute` from LDAP (if `UseUserLanguage` is `true`) +2. The `DefaultLanguage` setting for the customer diff --git a/docs/radius-interface-gateway-guide/deployment.md b/docs/radius-interface-gateway-guide/deployment.md index d77d00d..b90687f 100644 --- a/docs/radius-interface-gateway-guide/deployment.md +++ b/docs/radius-interface-gateway-guide/deployment.md @@ -64,11 +64,14 @@ openssl s_client -connect mobileid.swisscom.com:443 Note: The firewall on the Mobile ID API side has an IP-based whitelist. Therefore, the source IP address/range of the request sent to the Mobile ID API must be in the whitelist. If the IP address is unknown, the packet will be dropped and your request will time out. -## Configuration (Redis) +## Configuration -Here is a customer JSON configuration example. Add the JSON content example to your Redis database and change the configuration according to your preferences. You may configure one or multiple customers. +RIG supports two configuration sources for customer settings and I18N error messages: -Here is an I18N Error Message JSON configuration example. Add the JSON content example to your Redis database and change the configuration according to your preferences. This allows you to customize any Reply-Message content that is used for Access-Reject packets. +- **KeyValueStorage (Redis)** — Customer configurations and I18N messages are stored as JSON in Redis. This is the recommended approach for production and multi-node deployments, as configurations can be updated at runtime. +- **AppSettings (Environment Variables)** — All configuration is provided via environment variables. This is suitable for single-node deployments without Redis. + +For detailed configuration options including customer setup, LDAP integration, geofencing, Fortinet VSA, MFA method mapping, SMS notifications, and I18N error messages, see the [Configuration](/radius-interface-gateway-guide/configuration) page. ## Docker Run @@ -99,47 +102,239 @@ How to run a Docker application: docker run -d -p 1812:1812/udp --env-file mobileidch/mid-radius-rig ``` -Here is an env example file for the RIG application. Change the example according to your preferences. +### Environment File + +Below is an example `.env` file for a clustered RIG setup with Redis. Change the example according to your preferences. -At least the following parameters must be updated in the env file: +At least the following parameters must be updated: -- **`MID_CLIENT_CERTIFICATE`** — This shall be your base64-encoded Mobile ID API key. +- **`MID_CLIENT_CERTIFICATE`** — Your base64-encoded Mobile ID API key (PFX/PKCS#12, without password). ```bash base64 -w 0 ``` -- **`Schnittstellen__MobileIdClient__Host`** — This shall be the Mobile ID API endpoint, which is either `https://mobileid.swisscom.com` (Internet) or `https://195.65.233.218` (EC). +- **`Schnittstellen__MobileIdClient__Host`** — The Mobile ID API endpoint: `https://mobileid.swisscom.com` (Internet) or `https://195.65.233.218` ([Enterprise Connect](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html)). -## Docker Compose +- **`Schnittstellen__KeyValueStorage__ConnectionString`** — Your Redis connection string. -With Compose, you can create a YAML file to define the services and, with a single command, spin everything up or tear it all down. With this sample, you start multiple RIG container instances. +```bash +# Application Configuration +ASPNETCORE_ENVIRONMENT=Production + +# Base64-encoded MobileID Client Key (PFX/P12, PKCS#12, without password) +MID_CLIENT_CERTIFICATE=MIIJW*** + +# Serilog Log Configuration +# Valid levels: Verbose -> Debug -> Information -> Warning -> Error -> Fatal +Serilog__MinimumLevel__Default=Information +Serilog__MinimumLevel__Override__Microsoft=Warning +Serilog__MinimumLevel__Override__Microsoft.Hosting.Lifetime=Warning +Serilog__MinimumLevel__Override__Microsoft.Extensions.Diagnostics.HealthChecks=Error +Serilog__MinimumLevel__Override__Flexinets.Radius.RadiusServer=Information +Serilog__MinimumLevel__Override__Flexinets.Radius.Core=Information +Serilog__WriteTo__0__Args__outputTemplate={Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u4} [{CorrelationId}] {SourceContext} - {Message:lj}{NewLine}{Exception} + +# WebServer Port (used for health check endpoint) +WebServer__Port=80 + +# RADIUS Server Configuration +RadiusServer__Port=1812 +RadiusServer__OtpValiditySeconds=120 +RadiusServer__OtpMaxAllowedLoginAttempts=3 +RadiusServer__DuplicatePacketHandlingExpirationSeconds=120 + +# Configuration Sources (KeyValueStorage = Redis, AppSettings = Environment Variables) +RadiusServer__CustomerConfigSource=KeyValueStorage +RadiusServer__I18nMessagesSource=KeyValueStorage + +# Key-Value Storage (Redis) +Schnittstellen__KeyValueStorage__Storage=Redis +Schnittstellen__KeyValueStorage__ConnectionString=:6379,password=,ssl=False,abortConnect=False + +# MobileID Client +Schnittstellen__MobileIdClient__Host=https://mobileid.swisscom.com +Schnittstellen__MobileIdClient__ClientCertFromEnv=true +Schnittstellen__MobileIdClient__TransactionTimeoutSeconds=60 +Schnittstellen__MobileIdClient__SignatureTrust__ValidateCertTrust=true +Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignature=true +Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignaturePayload=true +Schnittstellen__MobileIdClient__ServerTrust__ValidateCertTrust=true + +# TrustStore Configuration +# Base64-encode each ROOT CA certificate (PEM format): +# $ base64 -w 0 Swisscom_Root_CA_4.cer +Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__0= +Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__1= +Schnittstellen__MobileIdClient__ServerTrust__TrustStore__0= +``` + +::: tip +The TrustStore certificates (Swisscom Root CA 4, Swisscom Root CA 2, SwissSign Gold CA-G2) are pre-encoded in the sample files available on [GitHub](https://github.com/MobileID-Strong-Authentication/mid-radius-rig). You can copy the base64 values directly from there. +::: + +### Single-Node Deployment (without Redis) + +For deployments that only use **SIM** and/or **APP** authentication (no OTP), RIG can run as a single container without Redis. In this mode, set the storage to `InMemory` and provide the customer configuration and I18N messages via environment variables: -Here is a `docker-compose.yaml` example with services defined as follows: +```bash +# Key-Value Storage (InMemory - no Redis required) +Schnittstellen__KeyValueStorage__Storage=InMemory -- **Mobile ID RADIUS Interface Gateway application** — from Docker Hub (or alternatively from Amazon ECR) -- **Redis database** using `redis` (or alternatively `keydb` may be used) -- **Redis web management tool** using `redis-commander` to manage the Redis database content -- **UDP network load balancer** using `nginx` with a custom `nginx.conf` configuration +# Configuration Sources (AppSettings = Environment Variables) +RadiusServer__CustomerConfigSource=AppSettings +RadiusServer__I18nMessagesSource=AppSettings +``` -Change the example according to your preferences. +The customer configuration is then provided as indexed environment variables. See the [Configuration](/radius-interface-gateway-guide/configuration#configuration-via-environment-variables) page for the full environment variable reference. -At least the following parameters must be updated in the YAML file: +::: warning +OTP authentication is **not supported** without Redis, as OTP session state requires shared storage across request cycles. +::: -- **`MID_CLIENT_CERTIFICATE`** — This shall be your base64-encoded Mobile ID API key. +## Docker Compose - ```bash - base64 -w 0 - ``` +With Compose, you can create a YAML file to define the services and, with a single command, spin everything up or tear it all down. The following example starts a complete RIG cluster with all required components. + +The services are: -- **`Schnittstellen__MobileIdClient__Host`** — This shall be the Mobile ID API endpoint, which is either `https://mobileid.swisscom.com` (Internet) or `https://195.65.233.218` (EC). +- **Mobile ID RADIUS Interface Gateway application** — from [Docker Hub](https://hub.docker.com/repository/docker/mobileidch/mid-radius-rig) (or alternatively from [Amazon ECR](https://gallery.ecr.aws/mobileidch/mid-radius-rig)) +- **Redis database** using `redis` (or alternatively `keydb` may be used) +- **Redis web management tool** using `redis-commander` to manage the Redis database content (customer configs, I18N messages) +- **UDP network load balancer** using `nginx` with a custom `nginx.conf` configuration -How to spin up using Docker Compose — make sure that both `docker-compose.yml` and `nginx.conf` exist in the same directory before you run the command below: +### docker-compose.yml + +Update `MID_CLIENT_CERTIFICATE`, `Schnittstellen__KeyValueStorage__ConnectionString`, and `Schnittstellen__MobileIdClient__Host` according to your setup. + +```yaml +services: + + mid-radius-rig: + # Option 1: Pull image from Docker Hub + image: mobileidch/mid-radius-rig:latest + # Option 2: Pull image from AWS ECR + # image: public.ecr.aws/r4c1w5d3/mid-radius-rig:latest + hostname: "rig_gateway" + ports: + - "1812/udp" + # Health check endpoint mapped to port 8055 on Docker host + - "8055:80/tcp" + links: + - redis + restart: always + environment: + - Serilog__MinimumLevel__Default=Information + - Serilog__MinimumLevel__Override__Microsoft=Warning + - Serilog__MinimumLevel__Override__Microsoft.Hosting.Lifetime=Warning + - Serilog__MinimumLevel__Override__Microsoft.Extensions.Diagnostics.HealthChecks=Error + - Serilog__MinimumLevel__Override__Flexinets.Radius.RadiusServer=Information + - Serilog__MinimumLevel__Override__Flexinets.Radius.Core=Information + - Serilog__WriteTo__0__Args__outputTemplate={Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u4} [{CorrelationId}] {SourceContext} - {Message:lj}{NewLine}{Exception} + - ASPNETCORE_ENVIRONMENT=Production + - MID_CLIENT_CERTIFICATE= + - RadiusServer__Port=1812 + - RadiusServer__OtpValiditySeconds=120 + - RadiusServer__OtpMaxAllowedLoginAttempts=3 + - RadiusServer__CustomerConfigSource=KeyValueStorage + - RadiusServer__I18nMessagesSource=KeyValueStorage + - RadiusServer__DuplicatePacketHandlingExpirationSeconds=120 + - Schnittstellen__KeyValueStorage__Storage=Redis + - Schnittstellen__KeyValueStorage__ConnectionString=redis:6379,password=,ssl=False,abortConnect=False + - Schnittstellen__MobileIdClient__Host=https://mobileid.swisscom.com + - Schnittstellen__MobileIdClient__ClientCertFromEnv=true + - Schnittstellen__MobileIdClient__SignatureTrust__ValidateCertTrust=true + - Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignature=true + - Schnittstellen__MobileIdClient__SignatureTrust__ValidateSignaturePayload=true + - Schnittstellen__MobileIdClient__ServerTrust__ValidateCertTrust=true + - Schnittstellen__MobileIdClient__TransactionTimeoutSeconds=60 + # TrustStore certificates (see env file sample for base64 values) + - Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__0= + - Schnittstellen__MobileIdClient__SignatureTrust__TrustStore__1= + - Schnittstellen__MobileIdClient__ServerTrust__TrustStore__0= + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/health"] + interval: 20s + retries: 3 + start_period: 10s + timeout: 3s + + redis: + image: redis:latest + container_name: "rig_redis" + hostname: "rig_redis" + ports: + - "6379:6379" + command: ["redis-server", "--appendonly", "yes"] + volumes: + - redis-data:/data + restart: always + + redis-commander: + image: rediscommander/redis-commander:latest + container_name: "rig_redis_commander" + environment: + - REDIS_HOSTS=local:redis:6379 + - HTTP_USER=admin + - HTTP_PASSWORD= + ports: + - 8081:8081 + depends_on: + - redis + restart: always + + nginx: + image: nginx:latest + container_name: "rig_nginx" + volumes: + - ./nginx.conf:/etc/nginx/nginx.conf + depends_on: + - mid-radius-rig + ports: + - "11812:1812/udp" + +volumes: + redis-data: +``` + +### nginx.conf + +The following `nginx.conf` configures a UDP load balancer that forwards RADIUS traffic to the RIG container(s). Place this file in the same directory as `docker-compose.yml`. + +```nginx +user nginx; + +events { + worker_connections 1000; +} +stream { + upstream rig-nginx { + server mid-radius-rig:1812; + } + + server { + listen 1812 udp; + proxy_pass rig-nginx; + } +} +``` + +### Starting the Cluster + +Make sure that both `docker-compose.yml` and `nginx.conf` exist in the same directory, then run: ```bash docker-compose up --scale mid-radius-rig=3 ``` +This starts 3 RIG instances behind the nginx UDP load balancer, with Redis for shared state. The health check endpoint is available at `http://localhost:8055/health`. + +You can verify the health check status with: + +```bash +docker inspect --format='{{json .State.Health}}' +``` + ## Integration Scenarios This chapter describes four different integration scenarios: diff --git a/docs/radius-interface-gateway-guide/imprint.md b/docs/radius-interface-gateway-guide/imprint.md index 877e661..1dd1894 100644 --- a/docs/radius-interface-gateway-guide/imprint.md +++ b/docs/radius-interface-gateway-guide/imprint.md @@ -1,11 +1,8 @@ # Imprint -Mobile ID ist eine Marke von Swisscom.
-Swisscom (Schweiz) AG +This legacy page is kept for compatibility with existing guide links. -Sitz: Ittigen +The current legal information for `docs.mobileid.ch` is available here: -Postadresse:
-Swisscom (Schweiz) AG
-Alte Tiefenaustrasse 6
-CH-3050 Bern
+- [Imprint](/legal/imprint) +- [Privacy Notice](/legal/privacy) diff --git a/docs/radius-interface-gateway-guide/introduction.md b/docs/radius-interface-gateway-guide/introduction.md index 82391d8..f5eab51 100644 --- a/docs/radius-interface-gateway-guide/introduction.md +++ b/docs/radius-interface-gateway-guide/introduction.md @@ -19,27 +19,30 @@ RADIUS users are typically defined in the format `user@domain`. However, Mobile ### Features Available -- Multitenancy -- Cloud-native microservice architecture (horizontal scalability) -- Authentication: Mobile ID SIM, Mobile ID App, OTP Text SMS -- Automatic authentication fallback with configurable priority -- MFA method selection via LDAP group membership (`memberOf`) -- MFA method "None" (temporarily disable MFA per user or group) -- Geofencing (whitelist/blacklist configuration, AD group-based, configurable confidence scores) -- LDAP(S) integration (`userPassword`, `mobile`, `preferredLanguage`, `midSerial`, `preferredMFA`) -- LDAP search scope and referral configuration -- Flexible LDAP search filters with multiple username placeholders -- LDAP authentication without admin/service user -- User Account Control attribute support -- Mobile ID user's serial number validation (optional) -- RADIUS Accounting -- RADIUS Class attribute in Access-Accept -- Custom RADIUS Reply Messages for Access-Reject -- Custom Text SMS notification for specific error events -- Accounting Webhook (forward accounting traffic to external systems) -- Supports Fortinet Vendor Specific Attributes (VSA) -- Support for Docker secrets via `_FILE` environment variables -- [BlastRADIUS](https://www.blastradius.fail/) mitigation — Message-Authenticator support ([CVE-2024-3596](https://nvd.nist.gov/vuln/detail/CVE-2024-3596)) +- **Multitenancy** — configure one or multiple customers, each with their own AP_ID, RADIUS shared secret, LDAP settings, and MFA preferences +- **Cloud-native microservice architecture** — horizontal scalability with Redis-based cluster synchronization +- **Single-node deployment** — run without Redis for SIM/APP-only setups (no OTP); ideal for smaller deployments and proof-of-concept environments +- **Authentication methods** — Mobile ID SIM digital signature, Mobile ID App digital signature, OTP via Text SMS +- **Automatic authentication fallback** with configurable method priority per customer +- **MFA method selection via LDAP** — per-user method assignment via LDAP attribute or group membership (`memberOf`) +- **MFA method "None"** — temporarily disable MFA per user or group +- **Geofencing** — whitelist/blacklist country configuration, LDAP group-based geofencing, configurable device and location confidence scores +- **LDAP(S) integration** — retrieve `userPassword`, `mobile`, `preferredLanguage`, serial number, and preferred MFA method; supports primary/secondary/tertiary host failover +- **LDAP search scope and referral** configuration +- **Flexible LDAP search filters** with `{username}`, `{domain}`, and `{userdn}` placeholders +- **LDAP authentication without admin/service user** — authenticate using the client's own credentials +- **User Account Control** attribute support (Active Directory) +- **Mobile ID serial number validation** — optionally validate the user's Mobile ID serial number against an LDAP attribute +- **RADIUS Accounting** with optional webhook forwarding to external systems +- **RADIUS Class attribute** in Access-Accept responses, mapped from LDAP group membership +- **Custom RADIUS Reply Messages** for Access-Reject packets, with I18N support (German, French, Italian, English) +- **Custom Text SMS notifications** for specific error events (e.g., serial number mismatch, geofencing errors) +- **SMS notifications for inactive Mobile ID users** — notify users to activate their Mobile ID account after a fallback authentication +- **Fortinet Vendor Specific Attributes (VSA)** — map LDAP groups to Fortinet group names and access profiles +- **Duplicate packet handling** — configurable deduplication to prevent redundant authentication sessions +- **Docker secrets support** via `_FILE` environment variables +- **Health check endpoint** — HTTP `/health` endpoint for container orchestration +- [**BlastRADIUS**](https://www.blastradius.fail/) **mitigation** — Message-Authenticator support ([CVE-2024-3596](https://nvd.nist.gov/vuln/detail/CVE-2024-3596)) ### Features Planned @@ -63,6 +66,15 @@ Since nodes need a way of communicating between them and considering the specifi Requests coming from outside of the RIG cluster reach a proxy service and are then dispatched to one appropriate RIG node. It is up to the proxy to select the right node, but any policy will work fine, as all RIG nodes have the same quality and level of data access, so any one of them could handle a request at any time. Of course, the proxy is responsible for carefully distributing the load on available nodes, but from the point of view of the RIG nodes, the functionality is the same, regardless of the chosen node. +### Single-Node Deployment (without Redis) + +For smaller deployments or proof-of-concept setups, RIG can be deployed as a single container instance without a Redis database. In this mode, session state is stored in-memory. This is suitable when: + +- Only **SIM** and/or **APP** authentication methods are used (no OTP) +- High availability and horizontal scaling are not required + +This deployment mode significantly reduces infrastructure requirements — only a single RIG container is needed. See the [Deployment](/radius-interface-gateway-guide/deployment) page for configuration details. + Moving one level down in the architectural view, the following diagram shows the main logical parts of the RIG service: +import EntraIntegrationFlow from '../../.vitepress/theme/components/EntraIntegrationFlow.vue' +import EntraUseCaseCards from '../../.vitepress/theme/components/EntraUseCaseCards.vue' +import EntraMigrationTimeline from '../../.vitepress/theme/components/EntraMigrationTimeline.vue' +import LanguageSwitcher from '../../.vitepress/theme/components/LanguageSwitcher.vue' +import VideoEmbed from '../../.vitepress/theme/components/VideoEmbed.vue' + + + + +
+Microsoft Entra ID ist die Identitätsplattform hinter Millionen von Unternehmensumgebungen. Mit der allgemeinen Verfügbarkeit von External MFA können Organisationen einen vertrauenswürdigen externen Authentisierungsanbieter in Entra ID einbinden und behalten dabei die volle Kontrolle über Conditional Access Policies. Mobile ID, betrieben von Swisscom, kombiniert hardwaregestützte SIM-Authentisierung, App-basiertes Push, gemeinsame Controls wie Number Matching und Transaction Signing, differenzierte Geofencing-Optionen und ein breiteres OIDC-Ecosystem, das inzwischen auch Mobile ID Passkeys umfasst. Im Entra-External-MFA-Ablauf konsumiert Entra das Provider-Ergebnis, während Mobile ID das Second-Factor-Erlebnis ausführt. +
+ + + Dieses Erklärvideo wurde mit Google NotebookLM basierend auf dem Mobile ID Artikel erstellt. + + +## Was ist Microsoft Entra External MFA? + +Microsoft Entra ID ist die zentrale Plattform für Identity and Access Management in Unternehmen, die Microsoft 365, Azure und Tausende verbundener Anwendungen nutzen. Bei der Anmeldung wertet Entra ID **Conditional Access Policies** aus, um zu entscheiden, ob eine zusätzliche Verifizierung nötig ist und welche Methode verwendet werden soll. + +Entra ID bietet bereits mehrere integrierte MFA-Methoden: Authenticator App, FIDO2 Security Keys, SMS und Telefonanrufe. Für Organisationen, die einen **externen Authentisierungsanbieter** einbinden mussten, war die einzige Option ein Legacy-Mechanismus namens **Custom Controls**. Custom Controls erlaubten die Weiterleitung von Benutzern an einen externen Anbieter, allerdings mit erheblichen Einschränkungen. Die externe Authentisierung wurde von Entra ID nicht vollständig als MFA anerkannt, was die Verwendung in Conditional Access Policies und Grant Controls einschränkte. + +**External MFA** ändert das. Seit Mai 2024 in der Public Preview und [seit März 2026 allgemein verfügbar](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/external-mfa-in-microsoft-entra-id-is-now-generally-available/4488926), ermöglicht External MFA einem externen Anbieter, die MFA-Anforderung von Entra ID über eine standardbasierte Provider-Integration zu erfüllen. In der Praxis kann damit der Conditional-Access-Grant-Control **Require multifactor authentication** erfüllt werden, und die Methode wird zusammen mit den übrigen Authentisierungsmethoden in Entra ID verwaltet. + +Das macht External MFA aber nicht mit jeder integrierten Entra-Methode identisch. Microsoft unterstützt External MFA derzeit nicht mit Authentication Strengths. Die zentrale Aussage ist präziser: External MFA ist ein unterstützter Weg, die MFA-Anforderung von Entra ID mit einem Drittanbieter zu erfüllen. + +Die Integration nutzt **OpenID Connect (OIDC)** zwischen Entra ID und dem externen Anbieter. Für Microsoft Entra External MFA ist das das von Microsoft dokumentierte Provider-Muster und nicht eine Relying Party, die den normalen Authorization Code Flow von Mobile ID verwendet. + +::: info +External MFA ersetzt Custom Controls, die Microsoft am [30. September 2026 abkündigen](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-external-method-manage) will. Organisationen, die noch Custom Controls verwenden, sollten ihre Migration jetzt planen. +::: + +## Wie funktioniert External MFA? + +Der Ablauf ist für den Endbenutzer einfach, technisch aber **nicht** identisch mit einer normalen Mobile-ID-Authorization-Code-Integration einer Relying Party. Im External-MFA-Szenario ruft Microsoft Entra ID den OIDC-Authorization-Endpoint des Providers mit seinem External-Provider-Implicit-Flow auf, einschliesslich Parametern wie `response_type=id_token`, `response_mode=form_post` und `id_token_hint`, das Benutzer und Tenant identifiziert. + +Mobile ID validiert diesen Entra-Kontext, führt den providerseitigen Second-Factor-Ablauf aus und gibt ein signiertes `id_token` an Entra ID zurück. Entra ID validiert dieses Token und prüft, ob die MFA-Anforderung erfüllt ist. + + + +Entra ID bleibt während des gesamten Prozesses die **Identity Control Plane**: Policy-Auswertung, Zugangsentscheide, Token-Ausstellung und Session Management. Mobile ID übernimmt den eigentlichen Authentisierungsschritt. + +Diese Trennung ist entscheidend. Entra steuert **wann** MFA erforderlich ist und konsumiert das Provider-Ergebnis. Mobile ID steuert **wie** der Benutzer sich im Provider-Ablauf authentisiert. Entra muss nicht verstehen, ob Mobile ID den zweiten Faktor intern mit SIM, App oder Passkey erbracht hat. + +## Warum Mobile ID als External MFA-Anbieter? + +Die meisten externen MFA-Anbieter bieten App-basierte Push-Benachrichtigungen. Mobile ID geht mit einer Kombination von Authentisierungsmethoden weiter, die Szenarien abdeckt, die andere Anbieter schlicht nicht adressieren können. + +Im breiteren Mobile-ID-Ecosystem gibt es inzwischen **drei starke Methoden**: **SIM**, **App** und **Passkeys**. Für Entra External MFA ist wichtig, dass Entra nicht zwischen diesen Methoden auswählt. Mobile ID führt den providerseitigen Ablauf aus, Entra konsumiert das erfolgreiche Ergebnis. + +### SIM-basierte Authentisierung: Keine App erforderlich + +Die [SIM-Methode](/rest-api-guide/introduction#mobile-id-sim---method) von Mobile ID nutzt die SIM-Karte (oder eSIM) als manipulationssicheres Hardware-Token, zertifiziert nach **EAL5+** (ISO/IEC 15408). Über 6 Millionen Schweizer SIM-Karten von Swisscom, Sunrise und Salt sind Mobile ID-fähig. + +Für Entra ID-Umgebungen bedeutet das: MFA funktioniert auf **jedem Mobilgerät**, einschliesslich einfacher Telefone ohne Smartphone-Betriebssystem. Keine App-Installation, keine App-Store-Abhängigkeit, keine Datenverbindung während der Authentisierung nötig. Für Organisationen mit Aussendienstmitarbeitenden, industriellen Umgebungen oder Mitarbeitenden ohne Smartphone ist das ein entscheidender Unterschied. + +Die zwei Faktoren sind die physische SIM-Karte (Besitz) und der persönliche Mobile ID PIN (Wissen). Die Authentisierung läuft über einen separaten verschlüsselten Kanal, unabhängig von der Internetverbindung. + +### App-basierte Authentisierung: Mehr als einfaches Push + +Die [Mobile ID App](/rest-api-guide/introduction#mobile-id-app---method) für iOS und Android geht weit über Standard-Push-Benachrichtigungen hinaus. Benutzer können sich per Fingerabdruck oder Gesichtserkennung authentisieren. **Number Matching** und **[Transaction Signing](/oidc-integration-guide/message-formats)** stehen sowohl mit Mobile ID SIM als auch mit Mobile ID App zur Verfügung. In der App werden diese Fähigkeiten mit smartphone-nativer UX und Biometrie kombiniert. **App-basiertes Geofencing** nutzt GPS-basierte Standortbestimmung plus integrierte Jailbreak- und Mock-Service-Erkennung, was GPS-Spoofing erschwert. In unterstützten Swisscom-SIM-Szenarien ist Geofencing auch über den Standortmechanismus des Mobilfunknetzes möglich. + +Die App basiert auf Technologie von Futurae, einem ETH-Zürich-Spin-off, und speichert Schlüssel im Trusted Execution Environment (TEE) des Geräts. + +### Passkey-Authentisierung: Phishing-resistente Browser-Fähigkeit + +Neben SIM und App unterstützt Mobile ID inzwischen auch [FIDO2 Passkeys](/oidc-integration-guide/passkey-authentication) in seinem OIDC Ecosystem. Passkeys sind kryptografisch an die Domain gebunden und dadurch resistent gegen URL-Spoofing. Benutzer registrieren ihre Passkeys auf [mobileid.ch](https://mobileid.ch/login) und können sie bei verbundenen Relying Parties verwenden, die für Mobile-ID-Passkeys konfiguriert sind. + +Für direkte Mobile-ID-OIDC-Integrationen lassen sich Passkeys mit Mobile-ID-spezifischen Controls wie passkey-orientierten ACR-Werten und `keyringId` kombinieren. Diese Controls gehören zur Standard-Integration der Relying Party mit Mobile ID und nicht zur Entra-External-MFA-Adminoberfläche. + +::: info +Im Kontext von Entra ID External MFA konsumiert Entra weiterhin nur das Ergebnis des Mobile-ID-Provider-Flows. Entra unterscheidet SIM, App und Passkey nicht als separate Mobile-ID-Methoden. Wenn Passkeys in der Mobile-ID-Provider-Konfiguration hinter einer Entra-Integration aktiviert sind, bleiben sie eine Mobile-ID-seitige Methodenwahl und keine Entra-seitige Einstellung. Details zu Passkeys und ihrer Rolle im breiteren Mobile-ID-Ecosystem finden Sie im Begleitartikel: [Mobile ID Passkeys: Phishing-resistente Authentisierung für Browser-Szenarien](/release-notes/posts/2026-03-30-mobile-id-passkeys). +::: + +### Schweizer Betrieb und Datenresidenz + +Mobile ID wird von Swisscom aus der Schweiz betrieben. Organisationen mit Anforderungen an die Datenresidenz oder einer Präferenz für europäisch betriebene Sicherheitsdienste können sicher sein, dass Authentisierungsdaten unter Schweizer Jurisdiktion bleiben. + +### Wo Mobile ID über natives MFA hinaus Mehrwert bietet + +Microsoft Authenticator ist ein solider Standard für Organisationen, die nur App-basiertes Push und TOTP benötigen. Mobile ID schafft dort klaren Mehrwert, wo die Anforderungen darüber hinausgehen: + +- **Teile der Belegschaft arbeiten ohne Smartphone.** +- **Die Authentisierung muss an einen definierten geografischen Bereich gebunden sein.** +- **Benutzer müssen Transaktionsdetails auf ihrem Gerät explizit bestätigen.** +- **Ein einziger MFA-Anbieter soll Entra ID, eigene Anwendungen, VPN und RADIUS abdecken.** + +Das sind Szenarien, in denen ein reiner App-Ansatz an seine Grenzen stösst. + +## Unternehmens-Anwendungsfälle + +Mobile ID adressiert ein breites Spektrum von Unternehmensszenarien über unterschiedliche Integrationsmodelle. SIM und App decken die breitesten Out-of-Band-Enterprise-Journeys ab. Passkeys ergänzen browser-zentrierte Journeys dort, wo WebAuthn-Unterstützung Ende-zu-Ende verfügbar ist. + + + +### Microsoft 365 MFA für Mitarbeitende + +Das häufigste Szenario: Absicherung des Zugangs zu Outlook, Teams, SharePoint und anderen Microsoft 365-Anwendungen. Wenn eine Conditional Access Policy MFA verlangt, authentisieren sich Mitarbeitende über Mobile ID anstelle von oder ergänzend zu Microsoft Authenticator. + +Das ist besonders wertvoll für Organisationen, die einen **einzigen MFA-Anbieter über alle Anwendungen hinweg** wollen, nicht nur für Microsoft-Dienste. Die Mobile ID-Authentisierungsmethoden — SIM, App und Passkeys — stehen über verschiedene Integrationsmodelle zur Verfügung: als Entra External MFA-Anbieter, über [Standard-OIDC](/oidc-integration-guide/introduction) für eigene Webanwendungen und via [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) für VPN- und Netzwerkzugang. + +### VPN und Remote Access + +Für VPN-Gateways, Citrix-Umgebungen, VDI-Sessions und Remote-Desktop-Zugang bietet Mobile ID MFA über das [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) oder direkt via OIDC. Sowohl SIM als auch App passen gut zu diesen Out-of-Band-Szenarien, weil keine der beiden Methoden von Bluetooth zu einem Hardware-Key abhängt. Sie bleiben damit auch dann praktisch, wenn die geschützte Session selbst remote oder client-gesteuert ist. + +Passkeys können browser-zentrierte Remote-Access-Journeys weiterhin ergänzen, wenn WebAuthn Ende-zu-Ende unterstützt wird. In VDI-, RDP- oder clientbasierten VPN-Flows sind sie jedoch oft weniger komfortabel, weil Browser-/WebAuthn-Unterstützung und Cross-Device-Handoff dort nicht durchgängig verfügbar sind. + +### Privileged Access Management + +Admin-Konten und der Zugang zu sensiblen Systemen erfordern das höchste Sicherheitsniveau. Entra ID Conditional Access Policies können auf bestimmte Admin-Rollen und sensible Anwendungen ausgerichtet werden, um External MFA via Mobile ID zu verlangen. Was Entra steuert, ist **wann** der zusätzliche Faktor erforderlich ist. Welche Mobile-ID-Methode im Provider-Ablauf verwendet wird, ist Sache von Mobile ID. + +Methodenspezifische Controls wie Mobile-ID-Passkey-only-ACRs, `keyringId` oder andere direkte Regeln zur Methodensteuerung gehören zu direkten Mobile-ID-OIDC-Integrationen ausserhalb der Entra-External-MFA-Adminoberfläche. + +### Hybride Belegschaft und Aussendienst + +Nicht alle Mitarbeitenden tragen ein Smartphone bei sich. Aussendienstmitarbeitende, Produktionspersonal oder Mitarbeitende in regulierten Umgebungen haben möglicherweise nur ein einfaches Mobiltelefon. Mit Mobile ID SIM erhalten diese Benutzer starke MFA ohne jegliche App-Installation. Büromitarbeitende können die Mobile ID App mit Biometrie für ein angenehmeres Erlebnis nutzen. Ein Anbieter deckt jeden Gerätetyp ab. + +
+ Unternehmens-Anwendungsfälle für Mobile ID als External MFA in Microsoft Entra ID: Microsoft 365, VPN, Privileged Access und hybride Belegschaftsszenarien +
+ +## Der Migrationspfad: Von Custom Controls zu External MFA + +Microsoft hat einen klaren Zeitplan gesetzt. Organisationen, die noch Custom Controls für MFA mit Drittanbietern verwenden, sollten vor dem Abkündigungstermin auf External MFA migrieren. + + + +Die Migration kann schrittweise erfolgen. Microsoft unterstützt den **parallelen Betrieb** von Custom Controls und External MFA während der Übergangsphase. Ein empfohlenes Vorgehen: + +
+
+
1
+
+

Mobile ID in Entra ID konfigurieren. Richten Sie Mobile ID im Entra Admin Center als External MFA-Methode ein und folgen Sie dabei der Konfigurationsanleitung.

+
+
+
+
2
+
+

Eine parallele Conditional Access Policy erstellen. Richten Sie die neue Policy zunächst auf eine klar definierte Testgruppe aus, damit der neue Ablauf kontrolliert eingeführt werden kann.

+
+
+
+
3
+
+

Den Authentisierungsfluss mit dieser Gruppe validieren. Prüfen Sie, ob Policy-Auswertung, Weiterleitung zu Mobile ID und erfolgreiche MFA-Rückgabe wie erwartet funktionieren.

+
+
+
+
4
+
+

Breit ausrollen und die Legacy-Policy abschalten. Weiten Sie die Policy anschliessend auf alle vorgesehenen Benutzer aus und deaktivieren Sie danach die bisherige Custom-Controls-Konfiguration.

+
+
+
+ +::: tip +Wenn Sie neu bei Mobile ID sind und es als External MFA-Anbieter in Betracht ziehen, übernimmt Swisscom den [Onboarding-Prozess](/oidc-integration-guide/getting-started). Sie erhalten die Application ID, Client ID und Discovery URL, die für die Konfiguration von External MFA in Entra ID benötigt werden. +::: + +## Erste Schritte + +Die Einrichtung von Mobile ID als External MFA-Anbieter in Entra ID erfordert drei Voraussetzungen: + +
+
+
1
+
+

Das Mobile ID-Onboarding abschliessen. Kontaktieren Sie Swisscom, um Ihre Integrationszugangsdaten zu erhalten und das Onboarding vollständig abzuschliessen. Alle Grundlagen dazu finden Sie unter Erste Schritte.

+
+
+
+
2
+
+

Ein Entra ID P1- oder P2-Abonnement bereitstellen. Conditional Access muss aktiviert sein, und die betroffenen Benutzer benötigen die passenden Lizenzen.

+
+
+
+
3
+
+

Ein Entra ID-Administratorkonto vorbereiten. Für die Konfiguration der externen MFA-Methode und der Conditional Access Policies ist mindestens die Rolle Authentication Policy Administrator erforderlich. Für die Erteilung der Admin-Zustimmung für die Anbieteranwendung wird mindestens die Rolle Privileged Role Administrator benötigt.

+
+
+
+ +Die Schritt-für-Schritt-Konfiguration ist im [Cloud Integration Guide](/oidc-integration-guide/cloud-integration-guide#microsoft-entra-id) dokumentiert, einschliesslich Conditional Access Policy-Setup, Admin Consent und optionalen Schritten zur Priorisierung von Mobile ID gegenüber Microsoft Authenticator. + + + +## Fazit + +Mit der allgemeinen Verfügbarkeit von External MFA in Microsoft Entra ID müssen Organisationen nicht mehr zwischen zentralem Identity Management und spezialisierter Authentisierung wählen. Entra ID bleibt die Policy Engine. Mobile ID liefert den providerseitigen zweiten Faktor über SIM, App und das breitere passkey-fähige Mobile-ID-Ecosystem, während Entra nur das External-MFA-Ergebnis konsumiert. + +In der Praxis bedeutet das einen MFA-Anbieter für Entra ID, Webanwendungen, VPN und RADIUS-Umgebungen, der Gerätetypen vom einfachen Mobiltelefon bis zu modernen passkey-fähigen Plattformen abdeckt. SIM und App bleiben besonders stark für Out-of-Band-Enterprise-Journeys, und Passkeys erweitern das Mobile-ID-Portfolio für phishing-resistente Browser-Szenarien, wenn Provider-Konfiguration und Plattformunterstützung dies zulassen. Dazu kommen eine in der Schweiz betriebene Infrastruktur mit standardbasierter OIDC-Integration und eine zukunftssichere Grundlage, weil External MFA die abgekündigten Custom Controls ersetzt und Mobile ID sich mit neuen Funktionen wie dem [Passkey Vault](/release-notes/posts/2026-03-30-mobile-id-passkeys#roadmap-the-mobile-id-passkey-vault) weiterentwickelt. + +Bei Fragen zu Mobile ID-Integrationen wenden Sie sich an [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). Allgemeine Informationen zum Service finden Sie auf [mobileid.ch](https://www.mobileid.ch/de). diff --git a/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.fr.md b/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.fr.md new file mode 100644 index 0000000..2dce2de --- /dev/null +++ b/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.fr.md @@ -0,0 +1,220 @@ +--- +title: "Mobile ID et Microsoft Entra ID : un MFA renforcé avec External Authentication" +date: 2026-03-27 +author: Mobile ID Team +description: "Microsoft Entra External MFA est disponible en version générale. Découvrez comment Mobile ID s'intègre comme fournisseur External MFA basé sur OIDC et comment SIM, App et Passkeys s'articulent." +thumbnail: /release-notes/img/entra-eam-thumb.png +lang: fr +keywords: + - Microsoft Entra External MFA + - Mobile ID + - fournisseur External MFA + - MFA Entra ID + - Conditional Access + - MFA par SIM + - MFA par App + - Passkeys + - MFA VPN +readingTime: 10 +layout: release-notes-post +--- + + + + + +
+Microsoft Entra ID est la plateforme d'identité utilisée par des millions d'environnements d'entreprise. Avec External MFA désormais disponible en version générale, les organisations peuvent intégrer un fournisseur d'authentification tiers de confiance dans Entra ID tout en conservant le contrôle total sur les politiques Conditional Access. Mobile ID, opéré par Swisscom, combine l'authentification matérielle via la SIM, l'authentification push via l'App, des contrôles partagés tels que le Number Matching et le Transaction Signing, des options de geofencing différenciées et un écosystème OIDC plus large qui inclut désormais les Mobile ID Passkeys. Dans le parcours Entra External MFA, Entra consomme le résultat du fournisseur tandis que Mobile ID exécute l'expérience de second facteur. +
+ + + Cette vidéo explicative a été créée avec Google NotebookLM à partir de l'article Mobile ID. + + +## Qu'est-ce que Microsoft Entra External MFA ? + +Microsoft Entra ID est la plateforme centrale de gestion des identités et des accès pour les entreprises utilisant Microsoft 365, Azure et des milliers d'applications connectées. Lorsqu'un utilisateur se connecte, Entra ID évalue les politiques **Conditional Access** pour déterminer si une vérification supplémentaire est nécessaire et quelle méthode utiliser. + +Entra ID propose déjà plusieurs méthodes MFA intégrées : application Authenticator, clés de sécurité FIDO2, SMS et appels téléphoniques. Pour les organisations qui devaient recourir à un **fournisseur d'authentification tiers**, la seule option était un mécanisme hérité appelé **Custom Controls**. Custom Controls permettait de rediriger les utilisateurs vers un fournisseur externe, mais avec des limitations significatives. L'authentification externe n'était pas pleinement reconnue comme MFA par Entra ID, ce qui limitait son utilisation dans les politiques Conditional Access et les contrôles d'accès. + +**External MFA** change la donne. Lancé en préversion publique en mai 2024 et [disponible en version générale depuis mars 2026](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/external-mfa-in-microsoft-entra-id-is-now-generally-available/4488926), External MFA permet à un fournisseur externe de satisfaire l'exigence MFA d'Entra ID au travers d'une intégration fournisseur fondée sur des standards. En pratique, cela permet de satisfaire le contrôle Conditional Access **Require multifactor authentication**, et la méthode est gérée avec les autres méthodes d'authentification dans Entra ID. + +Cela ne signifie pas pour autant qu'External MFA est identique à toutes les méthodes natives d'Entra. Microsoft ne prend actuellement pas en charge External MFA avec les Authentication Strengths. L'affirmation importante est plus précise : External MFA est une manière supportée de satisfaire l'exigence MFA d'Entra ID avec un fournisseur tiers. + +L'intégration utilise **OpenID Connect (OIDC)** entre Entra ID et le fournisseur externe. Pour Microsoft Entra External MFA, il s'agit du modèle fournisseur documenté par Microsoft, et non d'une relying party utilisant le flux Authorization Code habituel de Mobile ID. + +::: info +External MFA remplace Custom Controls, que Microsoft prévoit de [retirer le 30 septembre 2026](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-external-method-manage). Les organisations utilisant encore Custom Controls doivent planifier leur migration dès maintenant. +::: + +## Comment fonctionne External MFA ? + +Le flux reste simple pour l'utilisateur final, mais techniquement il **ne correspond pas** à une intégration Mobile ID classique en Authorization Code côté relying party. Dans le scénario External MFA, Microsoft Entra ID appelle l'endpoint d'autorisation OIDC du fournisseur avec son profil implicite pour fournisseur externe, en incluant notamment `response_type=id_token`, `response_mode=form_post` et un `id_token_hint` qui identifie l'utilisateur et le tenant. + +Mobile ID valide ce contexte Entra, exécute le parcours de second facteur côté fournisseur, puis renvoie un `id_token` signé à Entra ID. Entra ID valide ce token et vérifie si l'exigence MFA est satisfaite. + + + +Entra ID reste le **plan de contrôle des identités** tout au long du processus : évaluation des politiques, décisions d'accès, émission de tokens et gestion des sessions. Mobile ID gère l'étape d'authentification proprement dite. + +Cette séparation est essentielle. Entra décide **quand** le MFA est requis et consomme le résultat du fournisseur. Mobile ID décide **comment** l'utilisateur s'authentifie dans le parcours fournisseur. Entra n'a pas besoin de comprendre si Mobile ID a satisfait le second facteur via la SIM, l'App ou un Passkey. + +## Pourquoi choisir Mobile ID comme fournisseur External MFA ? + +La plupart des fournisseurs External MFA proposent des notifications push via une application. Mobile ID va plus loin avec une combinaison de méthodes d'authentification qui couvre des scénarios auxquels les autres fournisseurs ne peuvent tout simplement pas répondre. + +Dans l'écosystème Mobile ID au sens large, il existe désormais **trois méthodes fortes** : **SIM**, **App** et **Passkeys**. Pour Entra External MFA, le point important n'est pas qu'Entra choisisse entre elles ; ce n'est pas le cas. Mobile ID exécute le parcours côté fournisseur, et Entra consomme le résultat positif. + +### Authentification par SIM : sans application + +La [méthode SIM](/rest-api-guide/introduction#mobile-id-sim---method) de Mobile ID utilise la carte SIM (ou eSIM) comme token matériel inviolable, certifié **EAL5+** (ISO/IEC 15408). Plus de 6 millions de cartes SIM suisses de Swisscom, Sunrise et Salt sont compatibles Mobile ID. + +Pour les déploiements Entra ID, cela signifie que le MFA fonctionne sur **tout appareil mobile**, y compris les téléphones basiques sans système d'exploitation smartphone. Pas d'application à installer, pas de dépendance à un app store, pas de connexion de données nécessaire lors de l'authentification. Pour les organisations avec des collaborateurs sur le terrain, des environnements industriels ou des employés qui ne disposent pas de smartphone, c'est un facteur de différenciation essentiel. + +Les deux facteurs sont la carte SIM physique (possession) et le code PIN Mobile ID personnel (connaissance). L'authentification s'effectue via un canal chiffré séparé, indépendant de la connexion internet. + +### Authentification par App : bien plus qu'un simple push + +L'[App Mobile ID](/rest-api-guide/introduction#mobile-id-app---method) pour iOS et Android va bien au-delà des notifications push standard. Les utilisateurs peuvent s'authentifier par empreinte digitale ou reconnaissance faciale. **Le Number Matching** et le **[Transaction Signing](/oidc-integration-guide/message-formats)** sont disponibles à la fois avec Mobile ID SIM et avec Mobile ID App. Dans l'App, ces capacités sont combinées à une UX native smartphone et à la biométrie. **Le geofencing côté App** s'appuie sur la localisation GPS ainsi que sur des signaux intégrés de jailbreak et de services mock, ce qui rend le GPS spoofing plus difficile. Dans les scénarios pris en charge avec une Swisscom SIM, le geofencing est aussi possible via le mécanisme de localisation du réseau mobile. + +L'application repose sur la technologie de Futurae, une spin-off de l'ETH Zurich, et stocke les clés dans le Trusted Execution Environment (TEE) de l'appareil. + +### Authentification par Passkey : capacité résistante au phishing pour le navigateur + +Au-delà de la SIM et de l'App, Mobile ID prend désormais en charge les [Passkeys FIDO2](/oidc-integration-guide/passkey-authentication) dans son écosystème OIDC. Les Passkeys sont liés cryptographiquement au domaine et résistent donc au URL spoofing. Les utilisateurs enregistrent leurs Passkeys sur [mobileid.ch](https://mobileid.ch/login) et peuvent les utiliser auprès des relying parties connectées qui sont configurées pour les Mobile ID Passkeys. + +Pour les intégrations OIDC directes avec Mobile ID, les Passkeys peuvent être combinés avec des contrôles propres à Mobile ID tels que des valeurs ACR orientées Passkey et la gestion de `keyringId`. Ces contrôles relèvent de l'intégration standard entre la relying party et Mobile ID, et non de la surface d'administration Entra External MFA. + +::: info +Dans le contexte Entra ID External MFA, Entra consomme toujours uniquement le résultat du flux fournisseur Mobile ID. Entra ne distingue pas la SIM, l'App ou le Passkey comme méthodes Mobile ID séparées. Si les Passkeys sont activés dans la configuration du fournisseur Mobile ID derrière une intégration Entra, ils restent un choix de méthode côté Mobile ID et non un réglage côté Entra. Pour plus de détails sur les Passkeys et leur rôle dans l'écosystème Mobile ID, consultez l'article complémentaire : [Mobile ID Passkeys : authentification résistante au phishing pour les scénarios navigateur](/release-notes/posts/2026-03-30-mobile-id-passkeys). +::: + +### Exploitation suisse et résidence des données + +Mobile ID est opéré par Swisscom depuis la Suisse. Les organisations ayant des exigences de résidence des données ou une préférence pour des services de sécurité opérés en Europe peuvent avoir la certitude que les données d'authentification restent sous juridiction suisse. + +### Là où Mobile ID apporte une valeur ajoutée par rapport au MFA natif + +Microsoft Authenticator est un choix solide par défaut pour les organisations qui n'ont besoin que du push par application et du TOTP. Mobile ID apporte une valeur claire lorsque les exigences vont au-delà de ce socle : + +- **Une partie du personnel travaille sans smartphone.** +- **L'authentification doit être limitée à une zone géographique définie.** +- **Les utilisateurs doivent confirmer explicitement les détails d'une transaction sur leur appareil.** +- **Un fournisseur MFA unique doit couvrir Entra ID, les applications métiers, le VPN et les environnements RADIUS.** + +Ce sont des scénarios où une approche exclusivement basée sur une application atteint ses limites. + +## Cas d'usage en entreprise + +Mobile ID couvre un large éventail de scénarios d'entreprise à travers différents modèles d'intégration. La SIM et l'App couvrent les parcours d'entreprise hors bande les plus larges. Les Passkeys complètent les parcours centrés navigateur là où la prise en charge WebAuthn est disponible de bout en bout. + + + +### MFA Microsoft 365 pour les collaborateurs + +Le scénario le plus courant : sécuriser l'accès à Outlook, Teams, SharePoint et aux autres applications Microsoft 365. Lorsqu'une politique Conditional Access exige le MFA, les collaborateurs s'authentifient via Mobile ID au lieu de, ou en complément de, Microsoft Authenticator. + +Cela est particulièrement pertinent pour les organisations qui souhaitent un **fournisseur MFA unique pour toutes les applications**, et pas uniquement pour les services Microsoft. Les méthodes d'authentification Mobile ID — SIM, App et Passkeys — sont disponibles à travers différents modèles d'intégration : en tant que fournisseur Entra External MFA, via [OIDC standard](/oidc-integration-guide/introduction) pour les applications web personnalisées, et via le [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) pour l'accès VPN et réseau. + +### VPN et accès à distance + +Pour les passerelles VPN, les environnements Citrix, les sessions VDI et l'accès bureau à distance, Mobile ID fournit le MFA via le [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) ou directement via OIDC. La SIM comme l'App conviennent bien à ces scénarios hors bande, car aucune des deux méthodes ne dépend du Bluetooth vers une clé matérielle. Elles restent donc pratiques même lorsque la session protégée elle-même est distante ou pilotée par un client. + +Les Passkeys peuvent toujours compléter les parcours d'accès à distance centrés navigateur lorsque WebAuthn est pris en charge de bout en bout. En revanche, dans les flux VDI, RDP ou VPN basés sur un client, ils sont souvent moins pratiques parce que la prise en charge navigateur/WebAuthn et le handoff inter-appareils n'y sont pas disponibles de manière cohérente. + +### Gestion des accès privilégiés + +Les comptes administrateurs et l'accès aux systèmes sensibles exigent le niveau d'assurance le plus élevé. Les politiques Conditional Access d'Entra ID peuvent cibler des rôles d'administrateur spécifiques et des applications sensibles pour exiger External MFA via Mobile ID. Ce qu'Entra contrôle, c'est **quand** le facteur supplémentaire est requis. La méthode Mobile ID utilisée dans le parcours fournisseur relève de Mobile ID. + +Les contrôles spécifiques à une méthode, tels que les ACR Mobile ID orientés Passkey, `keyringId` ou d'autres règles de pilotage direct de la méthode, relèvent d'intégrations OIDC directes avec Mobile ID en dehors de la surface d'administration Entra External MFA. + +### Personnel hybride et de terrain + +Tous les collaborateurs ne disposent pas d'un smartphone. Les travailleurs de terrain, le personnel de production ou les employés dans des environnements réglementés peuvent n'avoir qu'un téléphone mobile basique. Avec Mobile ID SIM, ces utilisateurs bénéficient d'un MFA fort sans aucune installation d'application. Le personnel de bureau peut utiliser l'App Mobile ID avec la biométrie pour une expérience plus fluide. Un seul fournisseur couvre tous les types d'appareils. + +
+ Cas d'usage en entreprise pour Mobile ID comme External MFA dans Microsoft Entra ID : scénarios Microsoft 365, VPN, accès privilégiés et personnel hybride +
+ +## Le parcours de migration : de Custom Controls à External MFA + +Microsoft a établi un calendrier clair. Les organisations utilisant encore Custom Controls pour le MFA tiers doivent migrer vers External MFA avant la date de retrait. + + + +La migration peut se faire progressivement. Microsoft prend en charge l'exécution de Custom Controls et External MFA **en parallèle** pendant la période de transition. Une approche recommandée : + +
+
+
1
+
+

Configurer Mobile ID dans Entra ID. Déclarez Mobile ID comme méthode External MFA dans le centre d'administration Entra en vous appuyant sur le guide de configuration.

+
+
+
+
2
+
+

Créer une politique Conditional Access parallèle. Ciblez d'abord un groupe pilote clairement défini afin d'introduire le nouveau flux de manière contrôlée.

+
+
+
+
3
+
+

Valider le flux d'authentification avec ce groupe. Vérifiez que l'évaluation des politiques, la redirection vers Mobile ID et le retour MFA réussi fonctionnent comme prévu.

+
+
+
+
4
+
+

Étendre ensuite le déploiement et retirer l'ancienne politique. Appliquez la nouvelle politique à tous les utilisateurs concernés, puis désactivez la configuration Custom Controls existante.

+
+
+
+ +::: tip +Si vous découvrez Mobile ID et que vous l'envisagez comme fournisseur External MFA, Swisscom gère le processus d'[onboarding client](/oidc-integration-guide/getting-started). Vous recevrez l'Application ID, le Client ID et la Discovery URL nécessaires pour configurer External MFA dans Entra ID. +::: + +## Comment démarrer + +La mise en place de Mobile ID comme fournisseur External MFA dans Entra ID repose sur trois prérequis : + +
+
+
1
+
+

Finaliser l'onboarding Mobile ID. Contactez Swisscom pour recevoir vos identifiants d'intégration et terminer l'onboarding. Les informations de base sont disponibles dans premiers pas.

+
+
+
+
2
+
+

Disposer d'un abonnement Entra ID P1 ou P2. Conditional Access doit être activé et les licences doivent être attribuées aux utilisateurs concernés.

+
+
+
+
3
+
+

Prévoir un compte administrateur Entra ID. La configuration de la méthode External MFA et des politiques Conditional Access requiert au minimum le rôle Authentication Policy Administrator. L'octroi du consentement administrateur pour l'application du fournisseur requiert au minimum le rôle Privileged Role Administrator.

+
+
+
+ +La configuration pas à pas est documentée dans le [Cloud Integration Guide](/oidc-integration-guide/cloud-integration-guide#microsoft-entra-id), y compris la configuration de la politique Conditional Access, le consentement administrateur et les étapes optionnelles pour prioriser Mobile ID par rapport à Microsoft Authenticator. + + + +## Conclusion + +Avec External MFA désormais disponible en version générale dans Microsoft Entra ID, les organisations n'ont plus à choisir entre gestion centralisée des identités et authentification spécialisée. Entra ID reste le moteur de politiques. Mobile ID fournit le second facteur côté fournisseur au travers de la SIM, de l'App et d'un écosystème Mobile ID plus large, compatible avec les Passkeys, tandis qu'Entra ne consomme que le résultat External MFA. + +Concrètement, les organisations disposent ainsi d'un seul fournisseur MFA pour Entra ID, les applications web, le VPN et les environnements RADIUS, avec une couverture allant du téléphone mobile basique aux plateformes modernes compatibles Passkey. La SIM et l'App restent particulièrement fortes pour les parcours d'entreprise hors bande, tandis que les Passkeys étendent le portefeuille Mobile ID aux scénarios navigateur résistants au phishing lorsque la configuration fournisseur et la compatibilité de plateforme le permettent. À cela s'ajoutent une infrastructure opérée en Suisse et une intégration OIDC fondée sur les standards, qui constituent une trajectoire durable à mesure qu'External MFA remplace les Custom Controls dépréciés et que Mobile ID continue d'évoluer avec de nouvelles capacités comme le [Passkey Vault](/release-notes/posts/2026-03-30-mobile-id-passkeys#roadmap-the-mobile-id-passkey-vault). + +Pour toute question sur les intégrations Mobile ID, contactez [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). Pour des informations générales sur le service, consultez [mobileid.ch](https://www.mobileid.ch/fr). diff --git a/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.it.md b/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.it.md new file mode 100644 index 0000000..b65a374 --- /dev/null +++ b/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.it.md @@ -0,0 +1,220 @@ +--- +title: "Mobile ID e Microsoft Entra ID: MFA rafforzata con External Authentication" +date: 2026-03-27 +author: Mobile ID Team +description: "Microsoft Entra External MFA è generalmente disponibile. Scopri come Mobile ID si integra come provider External MFA basato su OIDC e come SIM, App e Passkeys si articolano correttamente." +thumbnail: /release-notes/img/entra-eam-thumb.png +lang: it +keywords: + - Microsoft Entra External MFA + - Mobile ID + - provider External MFA + - MFA Entra ID + - Conditional Access + - MFA basata su SIM + - MFA basata su app + - Passkeys + - VPN MFA +readingTime: 10 +layout: release-notes-post +--- + + + + + +
+Microsoft Entra ID è la piattaforma di identità alla base di milioni di ambienti aziendali. Con External MFA ora generalmente disponibile, le organizzazioni possono integrare un provider di autenticazione di terze parti affidabile in Entra ID, mantenendo il pieno controllo sulle policy Conditional Access. Mobile ID, operato da Swisscom, combina l'autenticazione hardware-grade basata su SIM, l'autenticazione push tramite app, controlli condivisi come Number Matching e Transaction Signing, opzioni di Geofencing differenziate e un ecosistema OIDC più ampio che ora include anche i Mobile ID Passkeys. Nel percorso Entra External MFA, Entra consuma il risultato del provider mentre Mobile ID esegue l'esperienza di secondo fattore. +
+ + + Questo video esplicativo è stato creato con Google NotebookLM sulla base dell'articolo Mobile ID. + + +## Cos'è Microsoft Entra External MFA? + +Microsoft Entra ID è la piattaforma centrale di gestione delle identità e degli accessi per le aziende che utilizzano Microsoft 365, Azure e migliaia di applicazioni connesse. Quando gli utenti effettuano il login, Entra ID valuta le policy **Conditional Access** per decidere se è necessaria una verifica aggiuntiva e quale metodo utilizzare. + +Entra ID offre già diversi metodi MFA integrati: Authenticator app, chiavi di sicurezza FIDO2, SMS e chiamate telefoniche. Per le organizzazioni che avevano bisogno di integrare un **provider di autenticazione di terze parti**, l'unica opzione era un meccanismo legacy chiamato **Custom Controls**. Custom Controls consentiva il reindirizzamento degli utenti a un provider esterno, ma con limitazioni significative. L'autenticazione esterna non veniva pienamente riconosciuta come MFA da Entra ID, il che ne limitava l'utilizzo nelle policy Conditional Access e nei grant controls. + +**External MFA** cambia questo scenario. Lanciata in anteprima pubblica nel maggio 2024 e [generalmente disponibile da marzo 2026](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/external-mfa-in-microsoft-entra-id-is-now-generally-available/4488926), External MFA consente a un provider esterno di soddisfare il requisito MFA di Entra ID tramite un'integrazione provider basata su standard. In pratica, può soddisfare il grant control di Conditional Access **Require multifactor authentication** ed è gestita insieme agli altri metodi di autenticazione in Entra ID. + +Questo non significa però che sia identica a ogni metodo integrato di Entra. Microsoft al momento non supporta External MFA con le Authentication Strengths. L'affermazione importante è più precisa: External MFA è un modo supportato per soddisfare il requisito MFA di Entra ID con un provider terzo. + +L'integrazione utilizza **OpenID Connect (OIDC)** tra Entra ID e il provider esterno. Per Microsoft Entra External MFA si tratta del pattern provider documentato da Microsoft, non di una relying party che usa il normale Authorization Code Flow di Mobile ID. + +::: info +External MFA sostituisce Custom Controls, che Microsoft prevede di [deprecare il 30 settembre 2026](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-external-method-manage). Le organizzazioni che utilizzano ancora Custom Controls dovrebbero pianificare la migrazione sin da ora. +::: + +## Come funziona External MFA? + +Il flusso resta semplice per l'utente finale, ma tecnicamente **non coincide** con una normale integrazione Mobile ID in Authorization Code da parte di una relying party. Nello scenario External MFA, Microsoft Entra ID chiama l'endpoint di autorizzazione OIDC del provider usando il proprio profilo implicit per provider esterni, includendo parametri come `response_type=id_token`, `response_mode=form_post` e un `id_token_hint` che identifica utente e tenant. + +Mobile ID valida questo contesto Entra, esegue il percorso di secondo fattore lato provider e restituisce a Entra ID un `id_token` firmato. Entra ID valida quel token e verifica se il requisito MFA è stato soddisfatto. + + + +Entra ID resta il **control plane dell'identità** durante l'intero processo: valutazione delle policy, decisioni di accesso, emissione dei token e gestione delle sessioni. Mobile ID gestisce il passaggio di autenticazione vero e proprio. + +Questa separazione è fondamentale. Entra decide **quando** è richiesto l'MFA e consuma il risultato del provider. Mobile ID decide **come** l'utente si autentica nel percorso provider. Entra non ha bisogno di capire se Mobile ID ha soddisfatto internamente il secondo fattore tramite SIM, App o Passkey. + +## Perché Mobile ID come provider External MFA? + +La maggior parte dei provider External MFA offre notifiche push basate su app. Mobile ID va oltre, con una combinazione di metodi di autenticazione che copre scenari che altri provider semplicemente non possono affrontare. + +Nel più ampio ecosistema Mobile ID esistono ora **tre metodi forti**: **SIM**, **App** e **Passkeys**. Per Entra External MFA, il punto importante non è che Entra scelga fra questi metodi; non lo fa. Mobile ID esegue il percorso lato provider e Entra consuma l'esito positivo. + +### Autenticazione basata su SIM: nessuna app necessaria + +Il [metodo SIM](/rest-api-guide/introduction#mobile-id-sim---method) di Mobile ID utilizza la scheda SIM (o eSIM) come token hardware tamper-proof, certificato **EAL5+** (ISO/IEC 15408). Oltre 6 milioni di SIM svizzere di Swisscom, Sunrise e Salt sono abilitate per Mobile ID. + +Per gli ambienti Entra ID, ciò significa che la MFA funziona su **qualsiasi dispositivo mobile**, compresi i telefoni di base senza sistema operativo smartphone. Nessuna app da installare, nessuna dipendenza dall'app store, nessuna connessione dati necessaria durante l'autenticazione. Per le organizzazioni con lavoratori sul campo, ambienti industriali o dipendenti che non utilizzano smartphone, questo rappresenta un differenziatore fondamentale. + +I due fattori sono la scheda SIM fisica (possesso) e il PIN Mobile ID personale (conoscenza). L'autenticazione avviene su un canale crittografato separato, indipendente dalla connessione internet. + +### Autenticazione tramite app: oltre il semplice push + +La [Mobile ID App](/rest-api-guide/introduction#mobile-id-app---method) per iOS e Android va ben oltre le notifiche push standard. Gli utenti possono autenticarsi con impronta digitale o riconoscimento facciale. **Il Number Matching** e il **[Transaction Signing](/oidc-integration-guide/message-formats)** sono disponibili sia con Mobile ID SIM sia con Mobile ID App. Nell'App, queste capacità si combinano con una UX nativa da smartphone e con la biometria. **Il Geofencing lato App** usa localizzazione GPS e segnali integrati di jailbreak e servizi mock, rendendo più difficile il GPS spoofing. Negli scenari supportati con Swisscom SIM, il Geofencing è possibile anche tramite il meccanismo di localizzazione della rete mobile. + +L'app è basata sulla tecnologia di Futurae, uno spin-off dell'ETH di Zurigo, e conserva le chiavi nel Trusted Execution Environment (TEE) del dispositivo. + +### Autenticazione Passkey: capacità browser resistente al phishing + +Oltre a SIM e App, Mobile ID supporta ora anche i [Passkeys FIDO2](/oidc-integration-guide/passkey-authentication) nel proprio ecosistema OIDC. I Passkeys sono legati crittograficamente al dominio e quindi resistenti allo URL spoofing. Gli utenti registrano i propri Passkeys su [mobileid.ch](https://mobileid.ch/login) e possono usarli presso le relying party connesse configurate per i Mobile ID Passkeys. + +Per le integrazioni OIDC dirette con Mobile ID, i Passkeys possono essere combinati con controlli specifici di Mobile ID come valori ACR orientati ai Passkeys e la gestione di `keyringId`. Questi controlli appartengono all'integrazione standard tra relying party e Mobile ID, non alla superficie amministrativa di Entra External MFA. + +::: info +Nel contesto di Entra ID External MFA, Entra continua a consumare solo il risultato del flusso provider Mobile ID. Entra non distingue SIM, App o Passkey come metodi Mobile ID separati. Se i Passkeys sono abilitati nella configurazione del provider Mobile ID dietro un'integrazione Entra, restano una scelta di metodo lato Mobile ID e non un'impostazione lato Entra. Per maggiori dettagli sui Passkeys e sul loro ruolo nell'ecosistema Mobile ID, consultare l'articolo correlato: [Mobile ID Passkeys: autenticazione resistente al phishing per scenari browser](/release-notes/posts/2026-03-30-mobile-id-passkeys). +::: + +### Operatività svizzera e residenza dei dati + +Mobile ID è operato da Swisscom dalla Svizzera. Le organizzazioni con requisiti di residenza dei dati o una preferenza per servizi di sicurezza operati in Europa possono contare sul fatto che i dati di autenticazione restano sotto la giurisdizione svizzera. + +### Dove Mobile ID aggiunge valore rispetto alla MFA nativa + +Microsoft Authenticator è un'opzione solida come default per le organizzazioni che necessitano solo di push basato su app e TOTP. Mobile ID aggiunge un valore chiaro quando i requisiti vanno oltre questa base: + +- **Parte del personale lavora senza smartphone.** +- **L'autenticazione deve essere vincolata a un'area geografica definita.** +- **Gli utenti devono confermare esplicitamente i dettagli della transazione sul proprio dispositivo.** +- **Un unico provider MFA deve coprire Entra ID, applicazioni custom, VPN e ambienti RADIUS.** + +Questi sono scenari in cui un approccio basato solo su app raggiunge i propri limiti. + +## Casi d'uso aziendali + +Mobile ID copre un'ampia gamma di scenari aziendali attraverso diversi modelli di integrazione. SIM e App coprono i percorsi enterprise out-of-band più ampi. I Passkeys completano i percorsi browser-centrici dove il supporto WebAuthn è disponibile end-to-end. + + + +### MFA per Microsoft 365 per i dipendenti + +Lo scenario più comune: proteggere l'accesso a Outlook, Teams, SharePoint e altre applicazioni Microsoft 365. Quando una policy Conditional Access richiede la MFA, i dipendenti si autenticano tramite Mobile ID al posto di, o insieme a, Microsoft Authenticator. + +Questo è particolarmente prezioso per le organizzazioni che desiderano un **unico provider MFA per tutte le applicazioni**, non solo per i servizi Microsoft. I metodi di autenticazione Mobile ID — SIM, App e Passkeys — sono disponibili attraverso diversi modelli di integrazione: come provider Entra External MFA, tramite [OIDC standard](/oidc-integration-guide/introduction) per applicazioni web custom, e tramite il [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) per l'accesso VPN e di rete. + +### VPN e accesso remoto + +Per gateway VPN, ambienti Citrix, sessioni VDI e accesso desktop remoto, Mobile ID fornisce la MFA tramite il [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) o direttamente via OIDC. Sia SIM sia App si adattano bene a questi scenari out-of-band, perché nessuno dei due metodi dipende dal Bluetooth verso una chiave hardware. Restano quindi pratici anche quando la sessione protetta è remota o guidata da un client. + +I Passkeys possono comunque completare percorsi di accesso remoto browser-centrici quando WebAuthn è supportato end-to-end. Nei flussi VDI, RDP o VPN basati su client, però, sono spesso meno pratici perché il supporto browser/WebAuthn e il cross-device handoff non sono disponibili in modo coerente. + +### Privileged Access Management + +Gli account amministratore e l'accesso a sistemi sensibili richiedono il massimo livello di garanzia. Le policy Conditional Access di Entra ID possono essere indirizzate a ruoli amministrativi specifici e applicazioni sensibili per richiedere External MFA tramite Mobile ID. Ciò che Entra controlla è **quando** il fattore aggiuntivo è richiesto. Quale metodo Mobile ID venga usato nel percorso provider è una responsabilità di Mobile ID. + +Controlli specifici di metodo, come gli ACR Mobile ID passkey-only, `keyringId` o altre regole di selezione diretta del metodo, appartengono a integrazioni OIDC dirette con Mobile ID al di fuori della superficie amministrativa di Entra External MFA. + +### Forza lavoro ibrida e sul campo + +Non tutti i dipendenti dispongono di uno smartphone. Lavoratori sul campo, personale di produzione o dipendenti in ambienti regolamentati possono avere solo un telefono cellulare di base. Con Mobile ID SIM, questi utenti ottengono una MFA robusta senza alcuna installazione di app. Il personale d'ufficio può utilizzare la Mobile ID App con biometria per un'esperienza più fluida. Un unico provider copre ogni tipo di dispositivo. + +
+ Casi d'uso aziendali per Mobile ID come External MFA in Microsoft Entra ID: scenari Microsoft 365, VPN, accesso privilegiato e forza lavoro ibrida +
+ +## Il percorso di migrazione: da Custom Controls a External MFA + +Microsoft ha fissato una tempistica chiara. Le organizzazioni che utilizzano ancora Custom Controls per la MFA di terze parti dovrebbero migrare a External MFA prima della scadenza di deprecazione. + + + +La migrazione può avvenire gradualmente. Microsoft supporta l'utilizzo simultaneo di Custom Controls ed External MFA durante il periodo di transizione. Un approccio consigliato: + +
+
+
1
+
+

Configurare Mobile ID in Entra ID. Impostate Mobile ID come metodo External MFA nell'admin center di Entra seguendo la guida alla configurazione.

+
+
+
+
2
+
+

Creare una policy Conditional Access parallela. Rivolgete la nuova policy inizialmente a un gruppo pilota ben definito, così da introdurre il nuovo flusso in modo controllato.

+
+
+
+
3
+
+

Validare il flusso di autenticazione con questo gruppo. Verificate che la valutazione delle policy, il reindirizzamento verso Mobile ID e il ritorno MFA avvengano come previsto.

+
+
+
+
4
+
+

Estendere il rollout e dismettere la policy legacy. Applicate poi la nuova policy a tutti gli utenti interessati e disabilitate la precedente configurazione basata su Custom Controls.

+
+
+
+ +::: tip +Se Mobile ID è una novità per la vostra organizzazione e lo state valutando come provider External MFA, Swisscom gestisce il processo di [onboarding del cliente](/oidc-integration-guide/getting-started). Riceverete l'Application ID, il Client ID e il Discovery URL necessari per configurare External MFA in Entra ID. +::: + +## Come iniziare + +Configurare Mobile ID come provider External MFA in Entra ID richiede tre prerequisiti: + +
+
+
1
+
+

Completare l'onboarding di Mobile ID. Contattate Swisscom per ricevere le credenziali di integrazione e portare a termine l'onboarding. Le informazioni di base sono raccolte nella sezione per iniziare.

+
+
+
+
2
+
+

Disporre di un abbonamento Entra ID P1 o P2. Conditional Access deve essere abilitato e le licenze devono essere assegnate agli utenti interessati.

+
+
+
+
3
+
+

Preparare un account amministratore Entra ID. La configurazione del metodo External MFA e delle policy Conditional Access richiede almeno il ruolo Authentication Policy Administrator. La concessione del consenso amministratore per l'applicazione del provider richiede almeno il ruolo Privileged Role Administrator.

+
+
+
+ +La configurazione passo per passo è documentata nella [Cloud Integration Guide](/oidc-integration-guide/cloud-integration-guide#microsoft-entra-id), compresa la configurazione delle policy Conditional Access, il consenso amministratore e i passaggi opzionali per dare priorità a Mobile ID rispetto a Microsoft Authenticator. + + + +## Conclusione + +Con External MFA ora generalmente disponibile in Microsoft Entra ID, le organizzazioni non devono più scegliere tra gestione centralizzata delle identità e autenticazione specializzata. Entra ID resta il motore di policy. Mobile ID fornisce il secondo fattore lato provider attraverso SIM, App e il più ampio ecosistema Mobile ID compatibile con i Passkeys, mentre Entra consuma solo il risultato External MFA. + +In pratica, questo significa poter contare su un unico provider MFA per Entra ID, applicazioni web, VPN e ambienti RADIUS, con copertura che va dai telefoni di base alle moderne piattaforme compatibili con i Passkeys. SIM e App restano particolarmente forti per i percorsi enterprise out-of-band, mentre i Passkeys ampliano il portafoglio Mobile ID verso scenari browser resistenti al phishing quando la configurazione del provider e il supporto della piattaforma lo consentono. Il tutto con un'infrastruttura operata in Svizzera, un'integrazione OIDC basata su standard e una base solida per il futuro, perché External MFA sostituisce i Custom Controls deprecati e Mobile ID continua a evolversi con nuove funzionalità come il [Passkey Vault](/release-notes/posts/2026-03-30-mobile-id-passkeys#roadmap-the-mobile-id-passkey-vault). + +Per domande sulle integrazioni Mobile ID, contattare [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). Per informazioni generali sul servizio, visitare [mobileid.ch](https://www.mobileid.ch/it). diff --git a/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.md b/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.md new file mode 100644 index 0000000..3947346 --- /dev/null +++ b/docs/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa.md @@ -0,0 +1,224 @@ +--- +title: "Mobile ID and Microsoft Entra ID: Stronger MFA with External Authentication" +date: 2026-03-27 +author: Mobile ID Team +description: "Microsoft Entra External MFA is generally available. See how Mobile ID integrates as an OIDC-based external MFA provider and how SIM, App and Passkeys fit together." +thumbnail: /release-notes/img/entra-eam-thumb.png +lang: en +keywords: + - Microsoft Entra External MFA + - Mobile ID + - External MFA provider + - Entra ID MFA + - Conditional Access + - SIM-based MFA + - app-based MFA + - Passkeys + - VPN MFA +readingTime: 10 +layout: release-notes-post +--- + + + + + +
+Microsoft Entra ID is the identity platform behind millions of enterprise environments. With External MFA now generally available, organizations can plug a trusted third-party authentication provider into Entra ID while keeping full control over Conditional Access policies. Mobile ID, operated by Swisscom, combines hardware-grade SIM authentication, app-based push, shared controls such as number matching and transaction signing, differentiated geofencing options, and a broader OIDC ecosystem that now also includes Mobile ID Passkeys. In the Entra External MFA journey, Entra consumes the provider result while Mobile ID runs the second-factor experience. +
+ + + This explainer video was created with Google NotebookLM based on the Mobile ID article. + + +## What Is Microsoft Entra External MFA? + +Microsoft Entra ID is the central identity and access management platform for enterprises using Microsoft 365, Azure and thousands of connected applications. When users sign in, Entra ID evaluates **Conditional Access policies** to decide whether additional verification is needed and which method to use. + +Entra ID already ships with several built-in MFA methods: Authenticator app, FIDO2 security keys, SMS and phone calls. For organizations that needed to bring in a **third-party authentication provider**, the only option was a legacy mechanism called **Custom Controls**. Custom Controls allowed redirecting users to an external provider, but with significant limitations. The external authentication was not fully recognized as MFA by Entra ID, which limited its use in Conditional Access policies and grant controls. + +**External MFA** changes this. Launched in public preview in May 2024 and [generally available since March 2026](https://techcommunity.microsoft.com/blog/microsoft-entra-blog/external-mfa-in-microsoft-entra-id-is-now-generally-available/4488926), External MFA lets an external provider satisfy Entra ID's MFA requirement through a standards-based provider integration. In practice, it can satisfy the Conditional Access grant control **Require multifactor authentication** and is managed alongside other authentication methods in Entra ID. + +That does not make it identical to every built-in Entra method. Microsoft currently does not support External MFA with Authentication Strengths. The important point is narrower and more precise: External MFA is a supported way to fulfill Entra ID's MFA requirement with a third-party provider. + +The integration uses **OpenID Connect (OIDC)** between Entra ID and the external provider. For Microsoft Entra External MFA, this is the provider pattern documented by Microsoft, not a relying party using Mobile ID's normal authorization code flow. + +::: info +External MFA replaces Custom Controls, which Microsoft plans to [deprecate on September 30, 2026](https://learn.microsoft.com/en-us/entra/identity/authentication/how-to-authentication-external-method-manage). Organizations still using Custom Controls should plan their migration now. +::: + +## How Does External MFA Work? + +The flow is straightforward for the end user, but technically it is **not** the same as a relying party's normal Mobile ID authorization code integration. In the External MFA scenario, Microsoft Entra ID calls the provider's OIDC authorization endpoint using its external-provider implicit-flow pattern, including parameters such as `response_type=id_token`, `response_mode=form_post`, and an `id_token_hint` that identifies the user and tenant. + +Mobile ID validates the Entra context, performs the provider-side second-factor journey, and returns a signed `id_token` to Entra ID. Entra ID validates that token and checks whether the MFA requirement is satisfied. + + + +Entra ID remains the **identity control plane** throughout the process: policy evaluation, access decisions, token issuance and session management. Mobile ID handles the authentication step itself. + +That separation matters. Entra decides **when** MFA is required and consumes the provider result. Mobile ID decides **how** the user authenticates inside the provider journey. Entra does not need to understand whether Mobile ID fulfilled the second factor with SIM, App, or Passkey. + +## Why Mobile ID as Your External MFA Provider? + +Most external MFA providers offer app-based push notifications. Mobile ID goes further with a combination of authentication methods that covers scenarios other providers simply cannot address. + +Across the broader Mobile ID ecosystem, there are now **three strong methods**: **SIM**, **App**, and **Passkeys**. For Entra External MFA, the important point is not that Entra chooses between them; it does not. Mobile ID runs the provider-side journey and Entra consumes the successful outcome. + +### SIM-Based Authentication: No App Required + +Mobile ID's [SIM method](/rest-api-guide/introduction#mobile-id-sim---method) uses the SIM card (or eSIM) as a tamper-proof hardware token, certified at **EAL5+** (ISO/IEC 15408). Over 6 million Swiss SIM cards from Swisscom, Sunrise and Salt are Mobile ID enabled. + +For Entra ID deployments, this means MFA works on **any mobile device**, including basic phones without a smartphone operating system. No app to install, no app store dependency, no data connection needed during authentication. For organizations with field workers, industrial environments, or employees who do not carry smartphones, this is a critical differentiator. + +The two factors are the physical SIM card (possession) and the personal Mobile ID PIN (knowledge). Authentication runs over a separate encrypted channel, independent of the internet connection. + +### App-Based Authentication: Beyond Simple Push + +The [Mobile ID App](/rest-api-guide/introduction#mobile-id-app---method) for iOS and Android goes well beyond standard push notifications. Users can authenticate with fingerprint or face recognition. **Number matching** and **[transaction signing](/oidc-integration-guide/message-formats)** are available with both Mobile ID SIM and Mobile ID App. On the App, these capabilities are combined with smartphone-native UX and biometrics. **App-based geofencing** uses GPS-based location determination plus built-in jailbreak and mock-service detection, which makes GPS spoofing more difficult. In supported Swisscom SIM scenarios, geofencing is also possible via the mobile-network location mechanism. + +The app is built on technology from Futurae, an ETH Zurich spin-off, and stores keys in the device's Trusted Execution Environment (TEE). + +### Passkey Authentication: Phishing-Resistant Browser Capability + +Beyond SIM and App, Mobile ID now also supports [FIDO2 passkeys](/oidc-integration-guide/passkey-authentication) across its OIDC ecosystem. Passkeys are cryptographically bound to the domain, which makes them immune to URL spoofing. Users register their passkeys on [mobileid.ch](https://mobileid.ch/login) and can use them across connected relying parties that are configured for Mobile ID passkeys. + +For direct Mobile ID OIDC integrations, passkeys can be combined with Mobile ID-specific controls such as passkey-oriented ACR values and `keyringId` handling. Those controls belong to the standard Mobile ID relying-party integration, not to the Entra External MFA admin surface. + +::: info +In the Entra ID External MFA context, Entra still consumes only the result of the Mobile ID provider flow. It does not distinguish SIM, App, or Passkey as separate Mobile ID methods. If passkeys are enabled for the Mobile ID provider configuration behind an Entra integration, they remain a Mobile ID-side method choice rather than an Entra-side setting. For broader passkey details, see the companion article: [Mobile ID Passkeys: Phishing-Resistant Authentication for Browser Scenarios](/release-notes/posts/2026-03-30-mobile-id-passkeys). +::: + +### Swiss Operation and Data Residency + +Mobile ID is operated by Swisscom from Switzerland. Organizations with data residency requirements or a preference for European-operated security services can be confident that authentication data stays within Swiss jurisdiction. + +### Where Mobile ID Adds Value Beyond Native MFA + +Microsoft Authenticator is a solid default for organizations that only need app-based push and TOTP. Mobile ID adds clear value when requirements go beyond that baseline: + +- **Parts of the workforce do not use smartphones.** +- **Authentication must be restricted to a defined geographic area.** +- **Users need to confirm transaction details explicitly on their device.** +- **One MFA provider should cover Entra ID, custom applications, VPN and RADIUS.** + +These are scenarios where an app-only approach hits its limits. + + + +## Enterprise Use Cases + +Mobile ID covers a wide range of enterprise scenarios through different integration models. SIM and App cover the broadest out-of-band enterprise journeys. Passkeys complement browser-centric journeys where WebAuthn support is available end to end. + + + +### Microsoft 365 MFA for Employees + +The most common scenario: securing access to Outlook, Teams, SharePoint and other Microsoft 365 applications. When a Conditional Access policy requires MFA, employees authenticate through Mobile ID instead of, or alongside, Microsoft Authenticator. + +This is particularly valuable for organizations that want a **single MFA provider across all applications**, not just Microsoft services. Mobile ID authentication methods — SIM, App and Passkeys — are available across different integration models: as an Entra External MFA provider, through [standard OIDC](/oidc-integration-guide/introduction) for custom web applications, and via the [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) for VPN and network access. + +### VPN and Remote Access + +For VPN gateways, Citrix environments, VDI sessions and remote desktop access, Mobile ID provides MFA through the [RADIUS Interface Gateway](/radius-interface-gateway-guide/introduction) or directly via OIDC. Both SIM and App fit well for these out-of-band scenarios because neither depends on Bluetooth to a hardware key. They remain practical even when the protected session itself is remote or client-driven. + +Passkeys can still complement browser-centric remote-access journeys where WebAuthn is supported end to end, but they are often less convenient in VDI, RDP or client-based VPN flows because browser/WebAuthn support and cross-device handoff are not consistently available there. + +### Privileged Access Management + +Admin accounts and access to sensitive systems require the highest level of assurance. Entra ID Conditional Access policies can target specific admin roles and sensitive applications to require External MFA via Mobile ID. What Entra controls is **when** the extra factor is required. Which Mobile ID method is used inside the provider journey is a Mobile ID concern. + +Method-specific controls such as Mobile ID passkey-only ACRs, `keyringId`, or other direct method-steering rules belong to direct Mobile ID OIDC integrations outside the Entra External MFA admin surface. + +### Hybrid and Field Workforce + +Not every employee carries a smartphone. Field workers, production staff, or employees in regulated environments may only have a basic mobile phone. With Mobile ID SIM, these users get strong MFA without any app installation. Office-based staff can use the Mobile ID App with biometrics for a smoother experience. One provider covers every device type. + +
+ Enterprise use cases for Mobile ID as External MFA in Microsoft Entra ID: Microsoft 365, VPN, privileged access, and hybrid workforce scenarios +
+ +## The Migration Path: From Custom Controls to External MFA + +Microsoft has set a clear timeline. Organizations still using Custom Controls for third-party MFA should migrate to External MFA before the deprecation deadline. + + + +The migration can happen gradually. Microsoft supports running Custom Controls and External MFA **in parallel** during the transition period. A recommended approach: + +
+
+
1
+
+

Configure Mobile ID in Entra ID. Set up Mobile ID as your External MFA method in the Entra admin center by following the configuration guide.

+
+
+
+
2
+
+

Create a parallel Conditional Access policy. Target a defined test group first so the new flow can be introduced without affecting the full workforce immediately.

+
+
+
+
3
+
+

Validate the authentication flow with that group. Confirm that policy evaluation, the redirect to Mobile ID and the successful MFA return all work as expected.

+
+
+
+
4
+
+

Roll out broadly and retire the legacy policy. Expand the policy to all intended users and then disable the old Custom Controls configuration.

+
+
+
+ +::: tip +If you are new to Mobile ID and considering it as your External MFA provider, Swisscom handles the [client onboarding](/oidc-integration-guide/getting-started) process. You will receive the Application ID, Client ID and Discovery URL needed to configure External MFA in Entra ID. +::: + +## How to Get Started + +Setting up Mobile ID as an External MFA provider in Entra ID requires three prerequisites: + +
+
+
1
+
+

Complete the Mobile ID onboarding. Contact Swisscom to receive your integration credentials and complete the onboarding process via getting started.

+
+
+
+
2
+
+

Use an Entra ID P1 or P2 subscription. Conditional Access must be enabled, and the relevant users must have the required licenses.

+
+
+
+
3
+
+

Prepare an Entra ID admin account. Configuring the external MFA method and Conditional Access policies requires at least the Authentication Policy Administrator role. Granting admin consent for the provider application requires at least the Privileged Role Administrator role.

+
+
+
+ +The step-by-step configuration is documented in the [Cloud Integration Guide](/oidc-integration-guide/cloud-integration-guide#microsoft-entra-id), including Conditional Access policy setup, admin consent, and optional steps to prioritize Mobile ID over Microsoft Authenticator. + + + +## Conclusion + +With External MFA now generally available in Microsoft Entra ID, organizations no longer have to choose between centralized identity management and specialized authentication. Entra ID stays the policy engine. Mobile ID delivers the provider-side second factor across SIM, App, and the broader passkey-capable Mobile ID ecosystem, while Entra consumes only the external MFA result. + +In practice, this gives organizations one MFA provider for Entra ID, web applications, VPN and RADIUS environments while covering device types from basic phones to modern passkey-capable platforms. SIM and App remain especially strong for out-of-band enterprise journeys, and passkeys extend the Mobile ID portfolio for phishing-resistant browser scenarios where the provider configuration and platform support allow it. Swiss-operated infrastructure and standards-based OIDC integration create a future-ready path as External MFA replaces deprecated Custom Controls and Mobile ID continues to evolve with new capabilities such as the [Passkey Vault](/release-notes/posts/2026-03-30-mobile-id-passkeys#roadmap-the-mobile-id-passkey-vault). + +For questions about Mobile ID integrations, reach out to [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). For general information about the service, visit [mobileid.ch](https://www.mobileid.ch/en). diff --git a/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.de.md b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.de.md new file mode 100644 index 0000000..120b630 --- /dev/null +++ b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.de.md @@ -0,0 +1,227 @@ +--- +title: "Mobile ID Passkeys: Phishing-resistente Authentisierung für Browser-Szenarien" +date: 2026-03-30 +author: Mobile ID Team +description: "Passkeys ermöglichen phishing-resistente Logins per Biometrie in unter 3 Sekunden. Mobile ID integriert sie nativ ins OIDC Ecosystem und zeigt, warum SIM und App weiterhin unverzichtbar sind." +thumbnail: /release-notes/img/passkeys-thumb.png +lang: de +readingTime: 12 +layout: release-notes-post +--- + + + + + +
+Microsoft blockiert täglich rund 7'000 Passwort-Angriffe pro Sekunde, und 47 % der Konsumenten brechen einen Kauf ab, wenn sie ihr Passwort vergessen. In einer Welt, in der Phishing nach wie vor der häufigste Angriffsvektor ist, braucht es eine grundlegend neue Antwort. Passkeys sind diese Antwort. Mobile ID integriert sie jetzt nativ in sein OIDC Ecosystem und kombiniert sie mit den bewährten Stärken von SIM und App. +
+ + + Dieses Erklärvideo wurde mit Google NotebookLM basierend auf dem Mobile ID Artikel erstellt. + + +## NIST AAL und ISO/IEC LoA: Referenzrahmen für Sicherheitsniveaus + +Bevor die einzelnen Methoden im Detail betrachtet werden, ist ein gemeinsames Verständnis der Sicherheitsstufen entscheidend. In der Praxis werden dafür zwei Referenzrahmen häufig herangezogen: NIST SP 800-63B (heute in Revision 4) mit drei Authenticator Assurance Levels (AAL1-AAL3) und ISO/IEC 29115:2013 mit vier Levels of Assurance (LoA1-LoA4). Beide beschreiben vom Prinzip her dasselbe: wie hoch die Vertrauens- bzw. Sicherheitsstufe einer Authentisierung ist. Verwirrend ist nur, dass die Skalen unterschiedlich benannt und nummeriert sind. Das höchste Niveau ist daher je nach Referenzrahmen entweder **AAL3** oder **LoA4**. + +**AAL1** verlangt lediglich eine Einzel-Faktor-Authentisierung. Passwörter, SMS-OTPs oder einfache Token erfüllen diese Stufe. Das Sicherheitsniveau ist gering. + +**AAL2** erfordert zwei unterschiedliche Faktoren. Zusätzlich muss für Online-Dienste eine phishing-resistente Option angeboten werden. Cloud-Synced Passkeys, TOTP-Generatoren, Mobile Push (wie Mobile ID SIM oder App) und Multi-Faktor-OTP-Geräte erfüllen AAL2. + +**AAL3** ist das höchste NIST-Niveau. Es verlangt phishing-resistente Public-Key-Kryptografie mit nicht exportierbarem privatem Schlüssel sowie zusätzliche Hardware-, Kryptografie- und Re-Authentisierungsanforderungen. Nur wenige Authenticatoren erfüllen diese Anforderungen vollständig: FIPS-zertifizierte Security Keys (z.B. YubiKey 5 FIPS Series), bestimmte Smartcards und Hardware Security Modules. + +## Was sind Passkeys? + +Passkeys sind eine benutzerfreundliche Implementierung des FIDO2-Standards und der WebAuthn-API. Sie ersetzen Passwörter durch kryptografische Schlüsselpaare und ermöglichen einen Login per Biometrie in unter 3 Sekunden. Das Kernprinzip: Der private Schlüssel verlässt das Gerät des Benutzers nie. Stattdessen signiert der Authenticator eine Challenge, die der Server mit dem öffentlichen Schlüssel verifiziert. + +Das Besondere an Passkeys ist das sogenannte Origin-Binding: Der Schlüssel ist kryptografisch an die Domain des Dienstes gebunden. Selbst wenn ein Benutzer auf eine perfekt nachgebaute Phishing-Seite gelangt, scheitert die Authentisierung, weil der Browser die falsche Domain erkennt und den Schlüssel nicht freigibt. + +## Passkey-Typen: Komfort vs. maximale Sicherheit + +Nicht alle Passkeys sind gleich. Je nach Schutzbedarf kommen unterschiedliche Typen zum Einsatz. Die Wahl hat direkte Auswirkungen auf das erreichbare Sicherheitsniveau. + +### Cloud-Synced Passkeys + +Cloud-Synced Passkeys werden über die Cloud-Infrastruktur des Plattformanbieters synchronisiert: Apple iCloud Keychain, Google Password Manager oder 3rd-Party-Manager wie 1Password. In den gängigen Consumer-Ökosystemen ist Cloud-Synchronisierung heute die Standard-User-Experience, weil sie Recovery und geräteübergreifende Nutzung maximiert. + +Der grosse Vorteil: Passkeys stehen auf allen Geräten desselben Ökosystems zur Verfügung. Geht ein Gerät verloren, bleibt der Zugang über andere Geräte erhalten. Die Synchronisierung erfolgt mit Ende-zu-Ende-Verschlüsselung. Cloud-Synced Passkeys können zudem mit Familienmitgliedern oder Freunden geteilt werden, was auch bedeutet, dass sie auf nicht vertrauenswürdige Geräte gelangen können. + +Sicherheitsniveau: **AAL2**. Da die Schlüssel exportierbar sind und in Cloud-Infrastrukturen liegen (die dem US CLOUD Act unterliegen), erfüllen sie nicht die Anforderungen für AAL3. + +### Device-Bound Passkeys + +Bei Device-Bound Passkeys verlässt der private Schlüssel die Sicherheits-Hardware nie. Typische Vertreter sind FIPS-zertifizierte Security Keys wie der YubiKey 5 FIPS Series (FIPS 140-2 Cert #3907, ca. CHF 100 bei Digitec). Diese bieten die höchste Sicherheit und sind AAL3-konform. + +Wichtig zu wissen: Standard-YubiKeys (ohne FIPS-Zertifizierung) genügen nicht für AAL3. Im September 2024 wurde zudem eine schwerwiegende Schwachstelle in der YubiKey 5 Series entdeckt, die nicht per Firmware-Update behoben werden kann, sondern einen physischen Austausch des Tokens erfordert. Dies illustriert ein grundsätzliches Problem physischer Token: Sicherheitslücken können teuer und aufwändig zu beheben sein. + +Sicherheitsniveau: **AAL3** (nur mit FIPS 140-2-Zertifizierung und Firmware 5.7 oder neuer). + +### Platform Authenticators + +Platform Authenticators sind direkt im Gerät verbaute Sicherheitsmodule wie Windows Hello (TPM), Apple Touch ID/Face ID (Secure Enclave) oder der Titan M2 Chip in Google-Pixel-Geräten. Sie können je nach Konfiguration als Cloud-Synced oder Device-Bound funktionieren. + +AAL3 ist nur erreichbar, wenn der Schlüssel nicht in die Cloud synchronisiert wird und die Hardware-Komponente FIPS-validiert ist. In der Praxis erfordert dies eine gerätegebundene Konfiguration oder einen externen Authenticator, der den privaten Schlüssel ausserhalb eines cloud-synchronisierten Credential Stores hält. + +### 3rd-Party Passkey Provider + +Seit iOS 17 und Android 14 können Drittanbieter als Passkey-Provider registriert werden. Die Credential Manager API (Android) bzw. AuthenticationServices (iOS) ermöglichen es Authentisierungs-Apps, Passkeys zu erstellen und zu verwalten, ohne dass der Benutzer auf den systemeigenen Passkey-Speicher angewiesen ist. + +Dies ist die technische Grundlage für den geplanten Mobile ID Passkey Vault: Die Mobile ID App wird selbst zum Passkey-Provider und kann Device-Bound Passkeys auf AAL3-Niveau verwalten, ohne dass physische Hardware-Token erforderlich sind. + +
+ Passkey-Typen im Sicherheitsvergleich: Cloud-Synced, Device-Bound und Platform Authenticators +
+ + + +## Passkey-Integration: Für Benutzer einfach, für Unternehmen komplex + +Passkeys versprechen eine einfache User Experience. Die technische Realität hinter den Kulissen ist jedoch anspruchsvoll. Eine vollständige Passkey-Infrastruktur erfordert: + +Ein **WebAuthn-Backend** mit FIDO2-Server-Library, Attestation-Validierung, Credential-Management und sicherer Schlüsselspeicherung. Ein **Credential-Lifecycle-Management** für Registrierung, Deaktivierung, Wiederherstellung und die Verwaltung mehrerer Passkeys pro Benutzer. **[Fallback-Mechanismen](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback)** für Benutzer ohne Passkey-fähiges Gerät oder bei fehlgeschlagener Authentisierung. **Compliance-Prüfungen** für regulierte Branchen, einschliesslich [AAGUID-Validierung](/oidc-integration-guide/passkey-authentication#rp-control-over-passkey-quality) gegen die FIDO Metadata Service (MDS) Datenbank und FIPS-Zertifizierungsprüfung. + +Mobile ID löst diese Komplexität: Relying Parties integrieren nicht die Passkey-Infrastruktur selbst, sondern den Mobile ID OIDC Service. Die Passkey-Registrierung und -Verwaltung findet zentral auf mobileid.ch statt. Ein Passkey wird einmal registriert und kann anschliessend bei allen angebundenen Relying Parties genutzt werden. + +Für Unternehmen bedeutet das eine Standard-OIDC-Integration mit [konfigurierbaren ACR-Werten](/oidc-integration-guide/passkey-authentication#passkey-acr-values), automatischem Fallback auf SIM, App oder SMS und der Sicherheit eines Partners wie Swisscom, der diese Lösungen selbst zum Schutz hochkritischer Infrastrukturen einsetzt. + +## Sicherheitsprofil nach Nutzungskontext + +Alle Mobile ID Methoden bieten starke Authentisierung. Die optimale Wahl hängt vom Einsatzszenario ab. Die zentrale Unterscheidung: Handelt es sich um ein offenes Browser-Szenario mit frei wählbarer URL oder um eine geschlossene Journey? + +### Browser-Journeys: Offene URLs und Phishing-Risiko + +Im Browser navigiert der Benutzer frei. Er kann auf Links in E-Mails klicken, URLs manuell eintippen oder über Suchmaschinen auf Seiten gelangen. Hier liegt das grösste Phishing-Risiko: Angreifer können Domains fälschen und Login-Seiten täuschend echt nachbauen. + +Passkeys bieten in diesem Szenario einen systemischen Vorteil. Durch kryptografisches Origin-Binding ist der Schlüssel fest an die echte Domain gebunden. Der Browser prüft automatisch, ob die anfordernde Domain mit der registrierten übereinstimmt. Eine Phishing-Seite auf `m0bileid.ch` erhält keinen Zugriff auf den Passkey, der für `mobileid.ch` registriert wurde. Das macht Passkeys zur ersten Wahl für reine Web-Logins. + +Wichtig: Auch Passkeys sind nicht frei von Angriffsvektoren. Malware auf der Plattform, kompromittierte Browser-Extensions oder Social Engineering auf Betriebssystemebene können jede Methode betreffen. Passkeys eliminieren spezifisch das URL-Spoofing-Problem. + +### Geschlossene Journeys: VPN, Remote Desktop, Kiosk, Native Apps + +Bei Logins in VPN-Clients, Remote-Desktop-/VDI-Umgebungen, am Kiosk-Terminal, bei nativen App-to-App-Wechseln oder beim Helpdesk-Callback greifen andere Schutzmechanismen. In diesen Szenarien gibt es keine frei wählbare URL. Die Verbindung wird durch den Client oder die Infrastruktur kontrolliert. URL-Spoofing ist kein Angriffsvektor. + +Mobile ID SIM und App bieten hier starke Sicherheit durch Hardware-Bindung (EAL5+), Number Matching, Transaction Signing und Geofencing in unterstützten Szenarien. App-basiertes Geofencing nutzt GPS plus Device-Integrity-Signale; unterstütztes SIM-Geofencing nutzt Standortdaten des Mobilfunknetzes. Passkeys sind in vielen dieser Szenarien gar nicht einsetzbar: WebAuthn ist eine Browser-Technologie, und VPN-Clients oder Remote-Desktop-Sitzungen (kein BLE-Kanal zum Authenticator!) unterstützen sie oft nicht. + +### SIM und App auch im Browser nutzbar + +SIM und App können auch für Browser-Logins eingesetzt werden. Nicht jeder Use Case erfordert maximale Phishing-Resistenz im Browser. Für viele Anwendungen ist die bewährte Push-basierte Authentisierung via SIM oder App eine pragmatische und sichere Lösung. Mobile ID deckt mit OIDC und REST API alle Szenarien ab. + +
+ Authentifizierungsmethoden im Überblick: Passkeys, SIM und App im Szenarien-Vergleich +
+ +## Warum SIM und App unverzichtbar bleiben + +Passkeys sind eine starke Ergänzung für Browser-Szenarien. SIM und App spielen ihre einzigartigen Stärken dort aus, wo WebAuthn an Grenzen stösst. + +### Mobile ID SIM + +Die SIM-basierte Methode nutzt die Mobile-ID-fähige SIM-Karte (oder eSIM) als sicheren Hardware-Token. Über 6 Millionen Schweizer SIM-Karten bei Swisscom, Sunrise, UPC und Salt sind Mobile-ID-fähig. Die kryptografischen Schlüssel werden direkt auf der SIM gespeichert, die nach dem Schutzprofil **EAL5+** (ISO/IEC 15408) und Evaluation Level E3 (ITSEC) zertifiziert ist. + +Die SIM-Methode benötigt keine App-Installation und keine App-Store-Abhängigkeit. Die Authentisierung wird als SIM-Toolkit-Overlay direkt über der Fachapplikation angezeigt. Sie funktioniert auf jedem Mobilgerät, auch auf Geräten ohne Smartphone-Betriebssystem, und über den GSM-Kanal. Über SMS-over-IP und WiFi ist die SIM-Methode auch bei fehlender Mobilfunkverbindung nutzbar. + +Beim Gerätewechsel steckt der Benutzer die SIM einfach um. Das Konto bleibt erhalten, ohne erneute Registrierung. Die SIM-basierte Standortverifikation ist besonders vertrauenswürdig, weil die Position im Mobilfunknetz schwer zu manipulieren ist. + +### Mobile ID App + +Die Mobile ID App (iOS und Android) bietet neben biometrischer Authentisierung ein breites Spektrum app-spezifischer Vorteile, die mit Passkeys allein nicht abbildbar sind: + +**Push-basierte Authentisierung** mit Biometrie oder Passcode als zweitem Faktor. **App-basiertes Geofencing** mit GPS-basierter Standortbestimmung und integrierter Jailbreak- und Mock-Service-Erkennung, die GPS-Spoofing erschwert. **Number Matching und [Transaction Signing](/oidc-integration-guide/message-formats)** stehen sowohl mit Mobile ID SIM als auch mit Mobile ID App zur Verfügung; in der App werden sie mit biometrischer Freigabe und reicherer smartphone-nativer UX kombiniert. **App-to-App-Wechsel** ermöglicht in Banking-Szenarien den automatisierten Wechsel von der Fachapplikation zur Mobile ID App und zurück. + +Die App basiert auf der Technologie von Futurae (ETH Zürich Spin-off) und nutzt das Trusted Execution Environment (TEE) des Geräts. Sie ist weltweit in freigegebenen Ländern über den App Store verfügbar. + +## Passkeys-Plus: Der Hybrid Auth Flow für nahezu AAL3 + +NIST AAL3 ist ein extrem hoher Sicherheitsstandard. Echtes AAL3 bedingt unter anderem ein nach FIPS 140-2 validiertes Hardware-Modul, was von der konkreten Gerätekonfiguration abhängt. Für hochkritische Systeme nutzt Swisscom intern bereits das Modell **Passkeys-Plus**, das ein sehr hohes Sicherheitsniveau anstrebt. + +Der Ansatz kombiniert zwei bereits existierende Komponenten zu einem Hybrid Auth Flow: + +**Schritt 1: Cloud-Sync Passkey (AAL2).** Der Benutzer authentisiert sich im Browser mit einem Passkey. Dies bietet breite Ökosystem-Unterstützung und phishing-resistentes Origin-Binding. + +**Schritt 2: Mobile ID Push Step-Up.** Anschliessend erhält der Benutzer einen Push auf sein Smartphone. Mobile ID Push nutzt Public-Key-Kryptografie mit nicht exportierbaren, gerätegebundenen Schlüsseln. Der Benutzer bestätigt mit Biometrie oder Passcode. Optional kommen Geoblocking und User-Consent-Anzeige hinzu. + +Die Kombination liefert: Origin-gebundenen Login plus gerätegebundenen, nicht exportierbaren Schlüssel plus expliziten User Consent plus Geolokation. Damit ist AAL3 in Deployments möglich, in denen der zweite Faktor auf geeigneter FIPS-140-2-zertifizierter Hardware läuft. Ob dies regulatorisch in jedem Fall als vollständiges AAL3 anerkannt wird, muss weiterhin pro Use Case, Hardwarebasis und Compliance-Rahmen beurteilt werden. Eine breitere Abdeckung mit FIPS-validierter Kryptografie und Device Attestation im Mobile ID Push Step ist erst nach zukünftigen Erweiterungen vollständig gegeben. + +Der Push-Schritt bleibt auf dem Smartphone. Am Desktop authentisiert sich der Benutzer lokal mit dem Passkey, und der Step-Up erfolgt out-of-band über das Telefon. + +
+ Hybrid-Authentifizierung für NIST AAL3: Cloud-Sync Passkey kombiniert mit Mobile ID Push Step-Up +
+ + + +## Mobile ID Authentication Levels: Granulare Steuerung über ACR-Werte + +Neben diesen externen Referenzrahmen definiert Mobile ID eigene Authentication Levels (AL2–AL4) als ACR-Werte im [OIDC Authorization Request](/oidc-integration-guide/getting-started#authorization-code-request). Diese Werte legen fest, welche Authentisierungsmethoden für einen Login erlaubt sind. Mobile ID orientiert sich dabei an der vierstufigen Logik aus ISO/IEC 29115. `AL4` bezeichnet entsprechend die höchste Mobile-ID-Sicherheitsstufe. Die vollständige ACR-Matrix ist im [OIDC Integration Guide](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr) dokumentiert. + + + +Im Modus `mid_al4_passkey` wird eine Passkey-only-Authentisierung erzwungen, die echte Phishing-Resistenz ohne schwache Fallbacks garantiert. Für maximale Flexibilität erlaubt `mid_al2_any` alle verfügbaren Methoden einschliesslich SMS. Mit `mid_al4_any` wird die Passkey-Authentisierung bevorzugt, mit Fallback auf SIM oder App. + +Während die meisten Provider Passkeys nur als einfachen Passwort-Ersatz mit unsicheren Wiederherstellungswegen anbieten (Google, PayPal, GitHub und selbst SBB erlauben OTP-E-Mail als Fallback), ermöglicht Mobile ID die Durchsetzung strenger Sicherheitspolicies und die Einschränkung auf FIPS-zertifizierte Authenticatoren über AAGUID-Validierung gegen die FIDO Metadata Service Datenbank. + +## Registration und Login Flows + +Der technische Rollout ist für Relying Parties denkbar einfach. + +### Zentrale Registrierung auf mobileid.ch + +Benutzer verwalten ihre Passkeys über das [MyMobileID Dashboard](/oidc-integration-guide/passkey-authentication#passkey-registration) auf mobileid.ch/login. Dort macht eine neue Kachel sichtbar, wo Passkeys zentral registriert und gepflegt werden. Die Passkeys werden auf der Domain m.mobileid.ch gespeichert und stehen anschliessend bei allen angebundenen Relying Parties zur Verfügung. + +Die neue Dashboard-Ansicht zeigt den Einstiegspunkt und die zentrale Verwaltung auf einen Blick: + + +

Die Kachel Manage Passkeys ist der zentrale Einstiegspunkt für das neue Passkey-Feature in MyMobileID. Hier starten Benutzer die Registrierung und Verwaltung ihrer Passkeys.

+
+ + +

Nach dem Öffnen sehen Benutzer ihre bereits registrierten Passkeys in einer übersichtlichen Verwaltungsansicht und können ihr Passkey-Portfolio bei Bedarf erweitern oder pflegen.

+
+ + + +### RP-Login via OIDC + +Für typische Login-Szenarien bei einer Relying Party steht im Dashboard neu auch der Mobile ID Check zur Verfügung. Damit können Benutzer ihre aktivierten Mobile ID Methoden in einem realistischen Authentisierungs-Use-Case testen: + + +

Die Kachel Mobile ID Check bietet einen einfachen Einstieg, um vorhandene Mobile ID Methoden wie SIM, App oder neu auch Passkey direkt im Dashboard zu testen.

+
+ + +

Ist bereits mindestens ein Passkey registriert, erscheint Passkey als auswählbare Methode. So lässt sich die neue Login-Option vor dem produktiven Einsatz in einem typischen [Login-Flow](/oidc-integration-guide/passkey-authentication#authentication-flow-oidc) schnell validieren.

+
+ +Je nach konfiguriertem [ACR-Wert](/oidc-integration-guide/passkey-authentication#passkey-acr-values) wird der passende Flow ausgelöst. Bei `mid_al4_passkey` wird ausschliesslich ein Passkey akzeptiert. Bei `mid_al2_any` kann der Benutzer zwischen Passkey, SIM, App oder SMS wählen. Bei Fehlern oder fehlenden Passkeys kann die RP einen sicheren [Fallback](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback) auf andere Methoden zulassen. + + + +## Roadmap: Der Mobile ID Passkey Vault + +Mit dem Mobile ID Passkey Vault befindet sich eine Roadmap-Lösung in Entwicklung, die AAL3 mit der Mobile ID App ermöglichen soll. Ziel ist ein Authenticator, der die strengen Anforderungen von AAL3 erfüllt und auf demselben Sicherheitsniveau spielt wie ein FIPS-zertifizierter Hardware-Key, dabei aber vollständig ins Mobile-ID-Ökosystem integriert bleibt. + +Gegenüber physischen Hardware-Keys bietet der Passkey Vault klare operative Vorteile: Die Passkey-Anmeldung lässt sich direkt mit Geoblocking und explizitem User Consent kombinieren, und der Authenticator lässt sich deutlich einfacher und kostengünstiger ausrollen und skalieren als teure Hardware-Token. + +Die Mobile ID App entwickelt sich damit zu einem skalierbaren Software-Authenticator, der die SIM-basierte Authentisierung mit Push-basierter MFA, Passkey-Funktionalität und einer reicheren smartphone-nativen UX für Transaction Signing und User Consent ergänzt. + +## Fazit: Alles aus einer Hand + +Mit der Einführung von Passkeys festigt Mobile ID seine Position als einzigartiges Ökosystem, das alle relevanten Authentisierungsmethoden unter einem Dach vereint. Passkeys für phishing-resistente Browser-Logins. SIM für höchste Hardware-Sicherheit ohne App-Installation, einschliesslich unterstütztem mobilfunkbasiertem Geofencing. App für GPS-basiertes Geofencing, Biometrie und weltweite Nutzbarkeit. Number Matching und Transaction Signing können mit SIM und App genutzt werden. Und mit dem Hybrid Auth Flow eine Lösung, die nahezu AAL3-Niveau erreicht, ohne dass jeder Benutzer einen Hardware-Token besitzen muss. + +Unternehmen profitieren von einer Standard-OIDC-Integration, Schweizer Datenhaltung und der Sicherheit eines Partners, der diese Lösungen selbst zum Schutz hochkritischer Infrastrukturen einsetzt. + +**Der Kunde entscheidet, welche Methode für seinen Use Case am besten passt. Mobile ID liefert die Flexibilität dazu.** + +*Mobile ID: die richtige Methode für jedes Szenario. Alles aus einem Ökosystem.* + +Bei Fragen zu Mobile ID Integrationen wenden Sie sich an [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). Allgemeine Informationen zum Service finden Sie auf [mobileid.ch](https://www.mobileid.ch/de). diff --git a/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.fr.md b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.fr.md new file mode 100644 index 0000000..2a67c52 --- /dev/null +++ b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.fr.md @@ -0,0 +1,227 @@ +--- +title: "Mobile ID Passkeys: authentification résistante au phishing pour les scénarios navigateur" +date: 2026-03-30 +author: Mobile ID Team +description: "Les Passkeys permettent des connexions résistantes au phishing par biométrie en moins de 3 secondes. Mobile ID les intègre nativement dans l'écosystème OIDC et montre pourquoi la SIM et l'App restent indispensables." +thumbnail: /release-notes/img/passkeys-thumb.png +lang: fr +readingTime: 12 +layout: release-notes-post +--- + + + + + +
+Microsoft bloque chaque jour environ 7'000 attaques par mot de passe par seconde, et 47 % des consommateurs abandonnent un achat lorsqu'ils ont oublié leur mot de passe. Dans un monde où le phishing reste le vecteur d'attaque le plus courant, une réponse fondamentalement nouvelle s'impose. Les Passkeys sont cette réponse. Mobile ID les intègre désormais nativement dans son écosystème OIDC et les combine avec les atouts éprouvés de la SIM et de l'App. +
+ + + Cette vidéo explicative a été créée avec Google NotebookLM à partir de l'article Mobile ID. + + +## NIST AAL : le cadre de référence pour les niveaux de sécurité + +Avant d'examiner chaque méthode en détail, il est essentiel de disposer d'une compréhension commune des niveaux de sécurité. Le standard NIST SP 800-63B définit trois Authenticator Assurance Levels (AAL) qui servent de cadre de référence dans les secteurs réglementés tels que la banque, la santé et le secteur public. + +**AAL1** exige uniquement une authentification à facteur unique. Les mots de passe, les SMS-OTP ou les tokens simples satisfont ce niveau. Le degré de sécurité est faible. + +**AAL2** requiert deux facteurs distincts. De plus, une option résistante au phishing doit être proposée pour les services en ligne. Les Cloud-Synced Passkeys, les générateurs TOTP, le Mobile Push (comme Mobile ID SIM ou App) et les appareils OTP multifacteurs satisfont AAL2. + +**AAL3** est le niveau le plus élevé. Il exige la cryptographie à clé publique, un module matériel validé FIPS 140 niveau 2 ou supérieur, des procédés résistants au phishing et une clé privée non exportable. Une ré-authentification après 15 minutes d'inactivité est également requise. Seuls quelques authenticateurs remplissent pleinement ces exigences : les clés de sécurité certifiées FIPS (par ex. YubiKey 5 FIPS Series), certaines smartcards et les Hardware Security Modules. + +## Que sont les Passkeys ? + +Les Passkeys sont une implémentation conviviale du standard FIDO2 et de l'API WebAuthn. Ils remplacent les mots de passe par des paires de clés cryptographiques et permettent une connexion par biométrie en moins de 3 secondes. Le principe fondamental : la clé privée ne quitte jamais l'appareil de l'utilisateur. L'authenticateur signe un challenge que le serveur vérifie à l'aide de la clé publique. + +La particularité des Passkeys réside dans le mécanisme d'Origin-Binding : la clé est liée cryptographiquement au domaine du service. Même si un utilisateur arrive sur une page de phishing parfaitement reproduite, l'authentification échoue car le navigateur détecte le domaine incorrect et ne libère pas la clé. + +## Types de Passkeys : confort vs. sécurité maximale + +Tous les Passkeys ne se valent pas. Selon le niveau de protection requis, différents types sont utilisés. Ce choix a un impact direct sur le niveau de sécurité atteignable. + +### Cloud-Synced Passkeys + +Les Cloud-Synced Passkeys sont synchronisés via l'infrastructure cloud du fournisseur de plateforme : Apple iCloud Keychain, Google Password Manager ou des gestionnaires tiers comme 1Password. Dans les principaux écosystèmes grand public, la synchronisation cloud est devenue l'expérience utilisateur par défaut, car elle maximise la récupération et l'usage multi-appareils. + +Le grand avantage : les Passkeys sont disponibles sur tous les appareils du même écosystème. En cas de perte d'un appareil, l'accès est maintenu via les autres appareils. La synchronisation est protégée par un chiffrement de bout en bout. Les Cloud-Synced Passkeys peuvent également être partagés avec des membres de la famille ou des amis, ce qui signifie aussi qu'ils peuvent se retrouver sur des appareils non fiables. + +Niveau de sécurité : **AAL2**. Les clés étant exportables et stockées dans des infrastructures cloud (soumises au US CLOUD Act), elles ne satisfont pas les exigences AAL3. + +### Device-Bound Passkeys + +Avec les Device-Bound Passkeys, la clé privée ne quitte jamais le matériel de sécurité. Les représentants typiques sont les clés de sécurité certifiées FIPS telles que la YubiKey 5 FIPS Series (FIPS 140-2 Cert #3907, env. CHF 100 chez Digitec). Elles offrent le niveau de sécurité le plus élevé et sont conformes AAL3. + +Point important : les YubiKeys standard (sans certification FIPS) ne suffisent pas pour AAL3. En septembre 2024, une vulnérabilité grave a été découverte dans la série YubiKey 5, qui ne peut pas être corrigée par mise à jour du firmware et nécessite un remplacement physique du token. Cela illustre un problème fondamental des tokens physiques : les failles de sécurité peuvent être coûteuses et complexes à corriger. + +Niveau de sécurité : **AAL3** (uniquement avec certification FIPS 140-2 et firmware 5.7 ou ultérieur). + +### Platform Authenticators + +Les Platform Authenticators sont des modules de sécurité intégrés directement dans l'appareil, comme Windows Hello (TPM), Apple Touch ID/Face ID (Secure Enclave) ou la puce Titan M2 dans les appareils Google Pixel. Selon la configuration, ils peuvent fonctionner en mode Cloud-Synced ou Device-Bound. + +AAL3 n'est atteignable que si la clé n'est pas synchronisée dans le cloud et si le composant matériel est validé FIPS. Dans la pratique, cela exige une configuration liée à l'appareil ou un authentificateur externe qui conserve la clé privée en dehors d'un magasin d'identifiants synchronisé dans le cloud. + +### Fournisseurs de Passkeys tiers + +Depuis iOS 17 et Android 14, des fournisseurs tiers peuvent s'enregistrer comme Passkey Provider. La Credential Manager API (Android) et AuthenticationServices (iOS) permettent aux applications d'authentification de créer et de gérer des Passkeys sans que l'utilisateur ne dépende du stockage natif de Passkeys du système. + +C'est le fondement technique du futur Mobile ID Passkey Vault : l'application Mobile ID deviendra elle-même un Passkey Provider et pourra gérer des Device-Bound Passkeys au niveau AAL3, sans nécessiter de tokens matériels physiques. + +
+ Types de Passkeys comparés en termes de sécurité : Cloud-Synced, Device-Bound et Platform Authenticators +
+ + + +## Intégration des Passkeys : simple pour les utilisateurs, complexe pour les entreprises + +Les Passkeys promettent une expérience utilisateur simple. La réalité technique en coulisse est toutefois exigeante. Une infrastructure Passkey complète nécessite : + +Un **backend WebAuthn** avec bibliothèque serveur FIDO2, validation de l'attestation, gestion des credentials et stockage sécurisé des clés. Un **Credential Lifecycle Management** pour l'enregistrement, la désactivation, la récupération et la gestion de plusieurs Passkeys par utilisateur. Des **[mécanismes de fallback](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback)** pour les utilisateurs sans appareil compatible Passkey ou en cas d'échec d'authentification. Des **vérifications de conformité** pour les secteurs réglementés, incluant la [validation AAGUID](/oidc-integration-guide/passkey-authentication#rp-control-over-passkey-quality) contre la base de données FIDO Metadata Service (MDS) et la vérification de certification FIPS. + +Mobile ID résout cette complexité : les Relying Parties n'intègrent pas l'infrastructure Passkey elles-mêmes, mais le service OIDC de Mobile ID. L'enregistrement et la gestion des Passkeys se font de manière centralisée sur mobileid.ch. Un Passkey est enregistré une seule fois et peut ensuite être utilisé auprès de toutes les Relying Parties connectées. + +Pour les entreprises, cela signifie une intégration OIDC standard avec des [valeurs ACR configurables](/oidc-integration-guide/passkey-authentication#passkey-acr-values), un fallback automatique vers SIM, App ou SMS, et la fiabilité d'un partenaire comme Swisscom, qui utilise lui-même ces solutions pour protéger des infrastructures hautement critiques. + +## Profil de sécurité selon le contexte d'utilisation + +Toutes les méthodes Mobile ID offrent une authentification forte. Le choix optimal dépend du scénario d'utilisation. La distinction centrale : s'agit-il d'un scénario navigateur ouvert avec URL librement accessible, ou d'un parcours fermé ? + +### Parcours navigateur : URL ouvertes et risque de phishing + +Dans le navigateur, l'utilisateur navigue librement. Il peut cliquer sur des liens dans des e-mails, saisir des URL manuellement ou accéder à des pages via des moteurs de recherche. C'est là que le risque de phishing est le plus élevé : les attaquants peuvent falsifier des domaines et reproduire des pages de connexion de manière trompeuse. + +Les Passkeys offrent dans ce scénario un avantage systémique. Grâce au mécanisme cryptographique d'Origin-Binding, la clé est liée de manière fixe au domaine authentique. Le navigateur vérifie automatiquement si le domaine demandeur correspond au domaine enregistré. Une page de phishing sur `m0bileid.ch` n'obtient aucun accès au Passkey enregistré pour `mobileid.ch`. Cela fait des Passkeys le premier choix pour les connexions purement web. + +Important : les Passkeys ne sont pas non plus exempts de vecteurs d'attaque. Les malwares sur la plateforme, les extensions de navigateur compromises ou l'ingénierie sociale au niveau du système d'exploitation peuvent affecter toute méthode. Les Passkeys éliminent spécifiquement le problème de l'usurpation d'URL. + +### Parcours fermés : VPN, Remote Desktop, Kiosk, Apps natives + +Pour les connexions via clients VPN, environnements Remote Desktop/VDI, terminaux kiosque, transitions App-to-App natives ou rappels du helpdesk, d'autres mécanismes de protection s'appliquent. Dans ces scénarios, il n'y a pas d'URL librement accessible. La connexion est contrôlée par le client ou l'infrastructure. L'usurpation d'URL n'est pas un vecteur d'attaque. + +Mobile ID SIM et App offrent ici une sécurité robuste grâce à la liaison matérielle (EAL5+), au Number Matching, au Transaction Signing et au geofencing dans les scénarios pris en charge. Le geofencing côté App s'appuie sur le GPS et des signaux d'intégrité du terminal ; le geofencing SIM pris en charge s'appuie sur les données de localisation du réseau mobile. Les Passkeys ne sont souvent pas utilisables dans nombre de ces scénarios : WebAuthn est une technologie navigateur, et les clients VPN ou les sessions Remote Desktop (pas de canal BLE vers l'authenticateur !) ne les prennent souvent pas en charge. + +### SIM et App également utilisables dans le navigateur + +SIM et App peuvent aussi être utilisés pour les connexions navigateur. Tous les cas d'utilisation ne nécessitent pas une résistance maximale au phishing dans le navigateur. Pour de nombreuses applications, l'authentification éprouvée par Push via SIM ou App constitue une solution pragmatique et sûre. Mobile ID couvre tous les scénarios avec OIDC et REST API. + +
+ Méthodes d'authentification en aperçu : Passkeys, SIM et App comparés par scénario +
+ +## Pourquoi SIM et App restent indispensables + +Les Passkeys sont un excellent complément pour les scénarios navigateur. SIM et App déploient leurs atouts uniques là où WebAuthn atteint ses limites. + +### Mobile ID SIM + +La méthode basée sur la SIM utilise la carte SIM compatible Mobile ID (ou eSIM) comme token matériel sécurisé. Plus de 6 millions de cartes SIM suisses chez Swisscom, Sunrise, UPC et Salt sont compatibles Mobile ID. Les clés cryptographiques sont stockées directement sur la SIM, certifiée selon le profil de protection **EAL5+** (ISO/IEC 15408) et le niveau d'évaluation E3 (ITSEC). + +La méthode SIM ne nécessite ni installation d'application ni dépendance à un App Store. L'authentification s'affiche sous forme d'overlay SIM Toolkit directement par-dessus l'application métier. Elle fonctionne sur tout appareil mobile, y compris les appareils sans système d'exploitation smartphone, et via le canal GSM. Grâce au SMS-over-IP et au WiFi, la méthode SIM est également utilisable en l'absence de couverture réseau mobile. + +Lors d'un changement d'appareil, l'utilisateur transfère simplement sa SIM. Le compte est conservé sans nouvel enregistrement. La vérification de localisation basée sur la SIM est particulièrement fiable, car la position dans le réseau mobile est difficile à manipuler. + +### Mobile ID App + +L'application Mobile ID (iOS et Android) offre, en plus de l'authentification biométrique, un large éventail d'avantages spécifiques à l'App qui ne sont pas reproductibles avec les seuls Passkeys : + +**Authentification par Push** avec biométrie ou code d'accès comme second facteur. **Geofencing côté App** avec localisation GPS et détection intégrée de jailbreak et de services de simulation, rendant le GPS spoofing plus difficile. **Le Number Matching et le [Transaction Signing](/oidc-integration-guide/message-formats)** restent disponibles à la fois avec Mobile ID SIM et Mobile ID App ; dans l'App, ils sont combinés à une validation biométrique et à une UX smartphone plus riche. **Le passage App-to-App** permet dans les scénarios bancaires le basculement automatisé de l'application métier vers l'application Mobile ID et retour. + +L'application repose sur la technologie de Futurae (spin-off de l'ETH Zurich) et utilise le Trusted Execution Environment (TEE) de l'appareil. Elle est disponible dans le monde entier, dans les pays autorisés, via l'App Store. + +## Passkeys-Plus : le Hybrid Auth Flow pour un niveau proche d'AAL3 + +NIST AAL3 est un standard de sécurité extrêmement élevé. Un véritable AAL3 exige entre autres un module matériel validé FIPS 140-2, ce qui dépend de la configuration concrète de l'appareil. Pour les systèmes hautement critiques, Swisscom utilise déjà en interne le modèle **Passkeys-Plus**, qui vise un niveau de sécurité très élevé. + +L'approche combine deux composants déjà existants en un Hybrid Auth Flow : + +**Étape 1 : Cloud-Sync Passkey (AAL2).** L'utilisateur s'authentifie dans le navigateur avec un Passkey. Cela offre une large prise en charge des écosystèmes et un Origin-Binding résistant au phishing. + +**Étape 2 : Mobile ID Push Step-Up.** L'utilisateur reçoit ensuite un Push sur son smartphone. Mobile ID Push utilise la cryptographie à clé publique avec des clés non exportables, liées à l'appareil. L'utilisateur confirme par biométrie ou code d'accès. En option, le géoblocage et l'affichage du consentement utilisateur s'ajoutent. + +La combinaison apporte : connexion liée à l'origine, plus clé liée à l'appareil et non exportable, plus consentement explicite de l'utilisateur, plus géolocalisation. Elle peut atteindre AAL3 dans les déploiements où le second facteur s'exécute sur un matériel approprié certifié FIPS 140-2. La reconnaissance réglementaire comme AAL3 complet doit toutefois toujours être évaluée au cas par cas, selon le cas d'utilisation, la base matérielle et le cadre de conformité. Une couverture plus large de cryptographie validée FIPS et de Device Attestation dans l'étape Mobile ID Push ne sera pleinement disponible qu'après de futures extensions. + +L'étape Push reste sur le smartphone. Sur le desktop, l'utilisateur s'authentifie localement avec le Passkey, et le Step-Up s'effectue out-of-band via le téléphone. + +
+ Authentification hybride pour NIST AAL3 : Cloud-Sync Passkey combiné avec Mobile ID Push Step-Up +
+ + + +## Mobile ID Authentication Levels : pilotage granulaire via les valeurs ACR + +En plus de ces cadres de référence externes, Mobile ID définit ses propres Authentication Levels (AL2–AL4) comme valeurs ACR dans l'[OIDC Authorization Request](/oidc-integration-guide/getting-started#authorization-code-request). Ces valeurs déterminent quelles méthodes d'authentification sont autorisées pour un login donné. Mobile ID s'aligne ici sur la logique à quatre niveaux d'ISO/IEC 29115. `AL4` désigne donc le niveau de sécurité Mobile ID le plus élevé. La matrice ACR complète est documentée dans le [guide d'intégration OIDC](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr). + + + +En mode `mid_al4_passkey`, une authentification exclusivement par Passkey est imposée, garantissant une véritable résistance au phishing sans fallbacks faibles. Pour une flexibilité maximale, `mid_al2_any` autorise toutes les méthodes disponibles, y compris le SMS. Avec `mid_al4_any`, l'authentification par Passkey est privilégiée, avec fallback sur SIM ou App. + +Alors que la plupart des fournisseurs proposent les Passkeys uniquement comme simple remplacement de mot de passe avec des chemins de récupération peu sûrs (Google, PayPal, GitHub et même les CFF autorisent l'OTP par e-mail comme fallback), Mobile ID permet l'application de politiques de sécurité strictes et la restriction aux authenticateurs certifiés FIPS via la validation AAGUID contre la base de données FIDO Metadata Service. + +## Flux d'enregistrement et de connexion + +Le déploiement technique est remarquablement simple pour les Relying Parties. + +### Enregistrement centralisé sur mobileid.ch + +Les utilisateurs gèrent leurs Passkeys via le [tableau de bord MyMobileID](/oidc-integration-guide/passkey-authentication#passkey-registration) sur mobileid.ch/login. Une nouvelle tuile indique immédiatement où les Passkeys peuvent être enregistrés et administrés de manière centralisée. Les Passkeys sont stockés sur le domaine m.mobileid.ch et sont ensuite disponibles auprès de toutes les Relying Parties connectées. + +Les nouvelles vues du tableau de bord montrent d'un coup d'oeil le point d'entrée et l'expérience de gestion centralisée : + + +

La tuile Manage Passkeys constitue le point d'entrée central de la nouvelle fonctionnalité Passkey dans MyMobileID. C'est ici que les utilisateurs démarrent l'enregistrement et la gestion de leurs Passkeys.

+
+ + +

Une fois la vue ouverte, les utilisateurs retrouvent leurs Passkeys déjà enregistrés dans un écran de gestion clair et peuvent compléter ou entretenir leur portefeuille de Passkeys si nécessaire.

+
+ + + +### Connexion RP via OIDC + +Pour les scénarios de connexion typiques chez une Relying Party, le tableau de bord inclut désormais aussi le Mobile ID Check. Il permet aux utilisateurs de tester leurs méthodes Mobile ID activées dans un cas d'usage d'authentification réaliste : + + +

La tuile Mobile ID Check offre un point d'entrée simple pour tester directement depuis le tableau de bord les méthodes Mobile ID disponibles, comme la SIM, l'App et désormais aussi le Passkey.

+
+ + +

Si au moins un Passkey a déjà été enregistré, Passkey apparaît comme méthode sélectionnable. La nouvelle option de connexion peut ainsi être validée rapidement dans un [flux de login](/oidc-integration-guide/passkey-authentication#authentication-flow-oidc) typique avant sa mise en production.

+
+ +Selon la [valeur ACR](/oidc-integration-guide/passkey-authentication#passkey-acr-values) configurée, le flux approprié est déclenché. Avec `mid_al4_passkey`, seul un Passkey est accepté. Avec `mid_al2_any`, l'utilisateur peut choisir entre Passkey, SIM, App ou SMS. En cas d'erreur ou d'absence de Passkeys, la RP peut autoriser un [fallback](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback) sécurisé vers d'autres méthodes. + + + +## Feuille de route : le Mobile ID Passkey Vault + +Avec le Mobile ID Passkey Vault, Mobile ID dispose d'une solution sur la feuille de route, actuellement en développement, conçue pour permettre l'AAL3 avec l'application Mobile ID. L'objectif est un authenticateur répondant aux exigences strictes d'AAL3 et évoluant au même niveau de sécurité qu'une clé matérielle certifiée FIPS, tout en restant pleinement intégré à l'écosystème Mobile ID. + +Par rapport aux clés matérielles physiques, le Passkey Vault offre des avantages opérationnels clairs : la connexion par Passkey peut être combinée directement avec le geoblocking et un consentement explicite de l'utilisateur, et l'authenticateur peut être déployé et étendu bien plus simplement et à moindre coût que des tokens matériels onéreux. + +L'application Mobile ID évolue ainsi vers un authenticateur logiciel scalable qui complète l'authentification basée SIM par un MFA push, des capacités Passkey et une UX smartphone plus riche pour le Transaction Signing et le consentement utilisateur. + +## Conclusion : tout d'un seul tenant + +Avec l'introduction des Passkeys, Mobile ID consolide sa position d'écosystème unique réunissant toutes les méthodes d'authentification pertinentes sous un même toit. Les Passkeys pour des connexions navigateur résistantes au phishing. La SIM pour la sécurité matérielle maximale sans installation d'application, y compris le geofencing fondé sur le réseau mobile lorsqu'il est pris en charge. L'App pour le geofencing GPS, la biométrie et l'utilisation mondiale. Le Number Matching et le Transaction Signing peuvent être utilisés avec la SIM comme avec l'App. Et avec le Hybrid Auth Flow, une solution atteignant un niveau proche d'AAL3, sans que chaque utilisateur n'ait besoin de posséder un token matériel. + +Les entreprises bénéficient d'une intégration OIDC standard, d'un hébergement des données en Suisse et de la fiabilité d'un partenaire qui utilise lui-même ces solutions pour protéger des infrastructures hautement critiques. + +**Le client décide quelle méthode convient le mieux à son cas d'utilisation. Mobile ID offre la flexibilité nécessaire.** + +*Mobile ID : la bonne méthode pour chaque scénario. Tout au sein d'un seul écosystème.* + +Pour toute question sur les intégrations Mobile ID, contactez [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). Pour des informations générales sur le service, visitez [mobileid.ch](https://www.mobileid.ch/fr). diff --git a/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.it.md b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.it.md new file mode 100644 index 0000000..e16ab18 --- /dev/null +++ b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.it.md @@ -0,0 +1,227 @@ +--- +title: "Mobile ID Passkeys: autenticazione resistente al phishing per scenari browser" +date: 2026-03-30 +author: Mobile ID Team +description: "I Passkeys consentono login resistenti al phishing tramite biometria in meno di 3 secondi. Mobile ID li integra nativamente nell'ecosistema OIDC e mostra perché SIM e App restano indispensabili." +thumbnail: /release-notes/img/passkeys-thumb.png +lang: it +readingTime: 12 +layout: release-notes-post +--- + + + + + +
+Microsoft blocca ogni giorno circa 7'000 attacchi alle password al secondo, e il 47% dei consumatori abbandona un acquisto quando dimentica la propria password. In un mondo in cui il phishing resta il vettore di attacco più diffuso, serve una risposta radicalmente nuova. I Passkeys sono questa risposta. Mobile ID li integra ora nativamente nel proprio ecosistema OIDC, combinandoli con i punti di forza consolidati di SIM e App. +
+ + + Questo video esplicativo è stato creato con Google NotebookLM sulla base dell'articolo Mobile ID. + + +## NIST AAL: il quadro di riferimento per i livelli di sicurezza + +Prima di analizzare nel dettaglio i singoli metodi, è fondamentale avere una comprensione condivisa dei livelli di sicurezza. Lo standard NIST SP 800-63B definisce tre Authenticator Assurance Levels (AAL), che nei settori regolamentati come banking, sanità e pubblica amministrazione fungono da quadro di riferimento. + +**AAL1** richiede soltanto un'autenticazione a fattore singolo. Password, SMS-OTP o semplici token soddisfano questo livello. Il grado di sicurezza è basso. + +**AAL2** richiede due fattori distinti. Inoltre, per i servizi online deve essere offerta un'opzione resistente al phishing. Cloud-Synced Passkeys, generatori TOTP, Mobile Push (come Mobile ID SIM o App) e dispositivi OTP multifattore soddisfano AAL2. + +**AAL3** è il livello più elevato. Richiede crittografia a chiave pubblica, un modulo hardware validato FIPS 140 Level 2 o superiore, procedure resistenti al phishing e una chiave privata non esportabile. Si applica inoltre una ri-autenticazione dopo 15 minuti di inattività. Solo pochi authenticator soddisfano pienamente questi requisiti: chiavi di sicurezza certificate FIPS (ad es. YubiKey 5 FIPS Series), determinate smartcard e Hardware Security Modules. + +## Cosa sono i Passkeys? + +I Passkeys sono un'implementazione user-friendly dello standard FIDO2 e dell'API WebAuthn. Sostituiscono le password con coppie di chiavi crittografiche e consentono il login tramite biometria in meno di 3 secondi. Il principio fondamentale: la chiave privata non lascia mai il dispositivo dell'utente. L'authenticator firma una challenge che il server verifica con la chiave pubblica. + +La particolarità dei Passkeys è il cosiddetto Origin-Binding: la chiave è legata crittograficamente al dominio del servizio. Anche se un utente raggiunge una pagina di phishing riprodotta alla perfezione, l'autenticazione fallisce perché il browser riconosce il dominio errato e non rilascia la chiave. + +## Tipi di Passkeys: comodità vs. massima sicurezza + +Non tutti i Passkeys sono uguali. A seconda del livello di protezione richiesto, si impiegano tipologie diverse. La scelta ha un impatto diretto sul livello di sicurezza raggiungibile. + +### Cloud-Synced Passkeys + +I Cloud-Synced Passkeys vengono sincronizzati attraverso l'infrastruttura cloud del fornitore della piattaforma: Apple iCloud Keychain, Google Password Manager o gestori di terze parti come 1Password. Nei principali ecosistemi consumer la sincronizzazione cloud è diventata l'esperienza utente predefinita, perché massimizza recovery e utilizzo su più dispositivi. + +Il grande vantaggio: i Passkeys sono disponibili su tutti i dispositivi dello stesso ecosistema. In caso di smarrimento di un dispositivo, l'accesso resta garantito tramite gli altri dispositivi. La sincronizzazione avviene con crittografia end-to-end. I Cloud-Synced Passkeys possono inoltre essere condivisi con familiari o amici, il che significa anche che possono finire su dispositivi non affidabili. + +Livello di sicurezza: **AAL2**. Poiché le chiavi sono esportabili e risiedono in infrastrutture cloud (soggette al CLOUD Act statunitense), non soddisfano i requisiti per AAL3. + +### Device-Bound Passkeys + +Con i Device-Bound Passkeys la chiave privata non lascia mai l'hardware di sicurezza. Rappresentanti tipici sono le chiavi di sicurezza certificate FIPS come la YubiKey 5 FIPS Series (FIPS 140-2 Cert #3907, ca. CHF 100 su Digitec). Offrono il massimo livello di sicurezza e sono conformi ad AAL3. + +È importante sapere che le YubiKey standard (senza certificazione FIPS) non sono sufficienti per AAL3. Nel settembre 2024 è stata inoltre scoperta una grave vulnerabilità nella YubiKey 5 Series, che non può essere corretta tramite aggiornamento firmware ma richiede la sostituzione fisica del token. Questo illustra un problema fondamentale dei token fisici: le falle di sicurezza possono essere costose e complesse da risolvere. + +Livello di sicurezza: **AAL3** (solo con certificazione FIPS 140-2 e firmware 5.7 o successivo). + +### Platform Authenticators + +I Platform Authenticators sono moduli di sicurezza integrati direttamente nel dispositivo, come Windows Hello (TPM), Apple Touch ID/Face ID (Secure Enclave) o il chip Titan M2 nei dispositivi Google Pixel. Possono funzionare come Cloud-Synced o Device-Bound a seconda della configurazione. + +AAL3 è raggiungibile solo se la chiave non viene sincronizzata nel cloud e il componente hardware è validato FIPS. In pratica ciò richiede una configurazione device-bound o un autenticatore esterno che mantenga la chiave privata al di fuori di uno store di credenziali sincronizzato nel cloud. + +### 3rd-Party Passkey Provider + +Da iOS 17 e Android 14 è possibile registrare provider di terze parti come Passkey Provider. La Credential Manager API (Android) e AuthenticationServices (iOS) consentono alle app di autenticazione di creare e gestire Passkeys senza che l'utente dipenda dall'archivio Passkey di sistema. + +Questa è la base tecnica per il futuro Mobile ID Passkey Vault: l'app Mobile ID diventerà essa stessa un Passkey Provider e potrà gestire Device-Bound Passkeys a livello AAL3, senza la necessità di token hardware fisici. + +
+ Tipi di Passkeys a confronto in termini di sicurezza: Cloud-Synced, Device-Bound e Platform Authenticators +
+ + + +## Integrazione Passkey: semplice per gli utenti, complessa per le aziende + +I Passkeys promettono un'esperienza utente semplice. La realtà tecnica dietro le quinte è tuttavia impegnativa. Un'infrastruttura Passkey completa richiede: + +Un **backend WebAuthn** con libreria server FIDO2, validazione dell'attestation, gestione delle credenziali e archiviazione sicura delle chiavi. Un **Credential-Lifecycle-Management** per registrazione, disattivazione, ripristino e gestione di più Passkeys per utente. **[Meccanismi di fallback](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback)** per utenti senza dispositivo compatibile con i Passkeys o in caso di autenticazione non riuscita. **Verifiche di compliance** per settori regolamentati, inclusa la [validazione AAGUID](/oidc-integration-guide/passkey-authentication#rp-control-over-passkey-quality) contro il database FIDO Metadata Service (MDS) e la verifica della certificazione FIPS. + +Mobile ID risolve questa complessità: le Relying Party non integrano l'infrastruttura Passkey in proprio, bensì il servizio OIDC di Mobile ID. La registrazione e la gestione dei Passkeys avviene centralmente su mobileid.ch. Un Passkey viene registrato una sola volta e può successivamente essere utilizzato presso tutte le Relying Party collegate. + +Per le aziende ciò significa un'integrazione OIDC standard con [valori ACR configurabili](/oidc-integration-guide/passkey-authentication#passkey-acr-values), fallback automatico su SIM, App o SMS e la sicurezza di un partner come Swisscom, che impiega queste soluzioni internamente per proteggere infrastrutture altamente critiche. + +## Profilo di sicurezza in base al contesto d'uso + +Tutti i metodi Mobile ID offrono un'autenticazione forte. La scelta ottimale dipende dallo scenario di impiego. La distinzione centrale: si tratta di uno scenario browser aperto con URL liberamente selezionabile o di un percorso chiuso? + +### Percorsi browser: URL aperti e rischio di phishing + +Nel browser l'utente naviga liberamente. Può cliccare su link nelle e-mail, digitare URL manualmente o raggiungere pagine tramite motori di ricerca. Qui risiede il maggiore rischio di phishing: gli attaccanti possono falsificare domini e riprodurre pagine di login in modo ingannevolmente realistico. + +I Passkeys offrono in questo scenario un vantaggio sistemico. Grazie all'Origin-Binding crittografico, la chiave è saldamente legata al dominio autentico. Il browser verifica automaticamente che il dominio richiedente corrisponda a quello registrato. Una pagina di phishing su `m0bileid.ch` non ottiene accesso al Passkey registrato per `mobileid.ch`. Questo rende i Passkeys la prima scelta per i login puramente web. + +Importante: anche i Passkeys non sono esenti da vettori di attacco. Malware sulla piattaforma, estensioni browser compromesse o social engineering a livello di sistema operativo possono colpire qualsiasi metodo. I Passkeys eliminano specificamente il problema dello URL-Spoofing. + +### Percorsi chiusi: VPN, Remote Desktop, Kiosk, App native + +Per i login tramite client VPN, ambienti Remote Desktop/VDI, terminali kiosk, passaggi nativi app-to-app o callback dell'helpdesk, entrano in gioco altri meccanismi di protezione. In questi scenari non esiste un URL liberamente selezionabile. La connessione è controllata dal client o dall'infrastruttura. Lo URL-Spoofing non è un vettore di attacco. + +Mobile ID SIM e App offrono qui una sicurezza robusta grazie a binding hardware (EAL5+), Number Matching, Transaction Signing e Geofencing negli scenari supportati. Il Geofencing lato App usa GPS e segnali di integrità del dispositivo; il Geofencing SIM supportato usa dati di localizzazione della rete mobile. In molti di questi scenari i Passkeys non sono nemmeno utilizzabili: WebAuthn è una tecnologia browser, e i client VPN o le sessioni Remote Desktop (nessun canale BLE verso l'authenticator!) spesso non li supportano. + +### SIM e App utilizzabili anche nel browser + +SIM e App possono essere impiegati anche per i login nel browser. Non tutti i casi d'uso richiedono la massima resistenza al phishing nel browser. Per molte applicazioni, la consolidata autenticazione push-based tramite SIM o App rappresenta una soluzione pragmatica e sicura. Mobile ID copre tutti gli scenari con OIDC e REST API. + +
+ Panoramica dei metodi di autenticazione: Passkeys, SIM e App nel confronto tra scenari +
+ +## Perché SIM e App restano indispensabili + +I Passkeys sono un valido complemento per gli scenari browser. SIM e App esprimono i loro punti di forza unici laddove WebAuthn raggiunge i propri limiti. + +### Mobile ID SIM + +Il metodo basato su SIM utilizza la SIM card compatibile con Mobile ID (o eSIM) come token hardware sicuro. Oltre 6 milioni di SIM card svizzere presso Swisscom, Sunrise, UPC e Salt sono compatibili con Mobile ID. Le chiavi crittografiche vengono memorizzate direttamente sulla SIM, certificata secondo il profilo di protezione **EAL5+** (ISO/IEC 15408) e il livello di valutazione E3 (ITSEC). + +Il metodo SIM non richiede alcuna installazione di app né dipendenza dall'App Store. L'autenticazione viene mostrata come overlay SIM Toolkit direttamente sopra l'applicazione in uso. Funziona su qualsiasi dispositivo mobile, anche su dispositivi privi di sistema operativo smartphone, e tramite il canale GSM. Attraverso SMS-over-IP e WiFi, il metodo SIM è utilizzabile anche in assenza di copertura di rete mobile. + +In caso di cambio dispositivo, l'utente semplicemente sposta la SIM. L'account resta attivo senza necessità di una nuova registrazione. La verifica della posizione basata su SIM è particolarmente affidabile, poiché la localizzazione nella rete mobile è difficile da manipolare. + +### Mobile ID App + +L'app Mobile ID (iOS e Android) offre, oltre all'autenticazione biometrica, un ampio spettro di vantaggi specifici dell'App non realizzabili con i soli Passkeys: + +**Autenticazione push-based** con biometria o passcode come secondo fattore. **Geofencing lato App** con localizzazione GPS e rilevamento integrato di jailbreak e servizi mock, che ostacola lo spoofing GPS. **Number Matching e [Transaction Signing](/oidc-integration-guide/message-formats)** restano disponibili sia con Mobile ID SIM sia con Mobile ID App; nell'App si combinano con approvazione biometrica e una UX nativa da smartphone più ricca. **Il passaggio app-to-app** consente negli scenari bancari la commutazione automatizzata dall'applicazione in uso all'app Mobile ID e ritorno. + +L'app si basa sulla tecnologia di Futurae (spin-off dell'ETH di Zurigo) e utilizza il Trusted Execution Environment (TEE) del dispositivo. È disponibile in tutto il mondo nei paesi abilitati tramite l'App Store. + +## Passkeys-Plus: l'Hybrid Auth Flow per un livello prossimo ad AAL3 + +NIST AAL3 è uno standard di sicurezza estremamente elevato. Un autentico AAL3 richiede tra l'altro un modulo hardware validato FIPS 140-2, il che dipende dalla configurazione concreta del dispositivo. Per i sistemi altamente critici, Swisscom utilizza già internamente il modello **Passkeys-Plus**, che mira a un livello di sicurezza molto elevato. + +L'approccio combina due componenti già esistenti in un Hybrid Auth Flow: + +**Fase 1: Cloud-Sync Passkey (AAL2).** L'utente si autentica nel browser con un Passkey. Questo offre un ampio supporto dell'ecosistema e Origin-Binding resistente al phishing. + +**Fase 2: Mobile ID Push Step-Up.** Successivamente l'utente riceve un push sul proprio smartphone. Mobile ID Push utilizza crittografia a chiave pubblica con chiavi non esportabili e legate al dispositivo. L'utente conferma con biometria o passcode. Opzionalmente si aggiungono il geoblocking e la visualizzazione del consenso utente. + +La combinazione fornisce: login con Origin-Binding, chiave legata al dispositivo e non esportabile, consenso esplicito dell'utente e geolocalizzazione. Può raggiungere AAL3 nei deployment in cui il secondo fattore gira su hardware idoneo certificato FIPS 140-2. Il riconoscimento regolatorio come AAL3 completo va tuttavia sempre valutato per singolo caso d'uso, base hardware e contesto di compliance. Una copertura più ampia di crittografia validata FIPS e di Device Attestation nel passaggio Mobile ID Push sarà pienamente disponibile solo dopo futuri ampliamenti. + +Il passaggio push resta sullo smartphone. Sul desktop l'utente si autentica localmente con il Passkey, e lo step-up avviene out-of-band tramite il telefono. + +
+ Autenticazione ibrida per NIST AAL3: Cloud-Sync Passkey combinato con Mobile ID Push Step-Up +
+ + + +## Mobile ID Authentication Levels: controllo granulare tramite valori ACR + +Oltre a questi quadri di riferimento esterni, Mobile ID definisce propri Authentication Levels (AL2–AL4) come valori ACR nell'[OIDC Authorization Request](/oidc-integration-guide/getting-started#authorization-code-request). Questi valori determinano quali metodi di autenticazione sono consentiti per un dato login. Mobile ID si orienta qui alla logica a quattro livelli di ISO/IEC 29115. `AL4` rappresenta quindi il livello di sicurezza Mobile ID più elevato. La matrice ACR completa è documentata nella [guida all'integrazione OIDC](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr). + + + +In modalità `mid_al4_passkey` viene forzata un'autenticazione esclusivamente tramite Passkey, che garantisce una reale resistenza al phishing senza fallback deboli. Per la massima flessibilità, `mid_al2_any` ammette tutti i metodi disponibili, incluso SMS. Con `mid_al4_any`, l'autenticazione tramite Passkey è preferita, con fallback su SIM o App. + +Mentre la maggior parte dei provider offre i Passkeys come semplice sostituto della password con percorsi di recupero insicuri (Google, PayPal, GitHub e persino le FFS consentono OTP via e-mail come fallback), Mobile ID permette l'applicazione di policy di sicurezza rigorose e la restrizione ad authenticator certificati FIPS tramite validazione AAGUID contro il database FIDO Metadata Service. + +## Flussi di registrazione e login + +Il rollout tecnico per le Relying Party è estremamente semplice. + +### Registrazione centralizzata su mobileid.ch + +Gli utenti gestiscono i propri Passkeys tramite il [dashboard MyMobileID](/oidc-integration-guide/passkey-authentication#passkey-registration) su mobileid.ch/login. Un nuovo riquadro mostra subito dove i Passkeys possono essere registrati e gestiti in modo centralizzato. I Passkeys vengono memorizzati sul dominio m.mobileid.ch e sono successivamente disponibili presso tutte le Relying Party collegate. + +Le nuove viste del dashboard mostrano a colpo d'occhio il punto di accesso e la gestione centralizzata: + + +

Il riquadro Manage Passkeys è il punto di accesso centrale per la nuova funzionalità Passkey in MyMobileID. Da qui gli utenti avviano la registrazione e la gestione dei propri Passkeys.

+
+ + +

Una volta aperta la vista, gli utenti trovano i Passkeys già registrati in una schermata di gestione chiara e possono ampliare o mantenere il proprio portafoglio Passkey secondo necessità.

+
+ + + +### Login della RP via OIDC + +Per i tipici scenari di login presso una Relying Party, il dashboard include ora anche il Mobile ID Check. Consente agli utenti di testare i metodi Mobile ID attivati in un caso d'uso di autenticazione realistico: + + +

Il riquadro Mobile ID Check offre un accesso semplice per testare direttamente dal dashboard i metodi Mobile ID disponibili, come SIM, App e ora anche Passkey.

+
+ + +

Se è già stato registrato almeno un Passkey, Passkey compare come metodo selezionabile. In questo modo la nuova opzione di login può essere verificata rapidamente in un tipico [flusso di login](/oidc-integration-guide/passkey-authentication#authentication-flow-oidc) prima dell'uso in produzione.

+
+ +A seconda del [valore ACR](/oidc-integration-guide/passkey-authentication#passkey-acr-values) configurato, viene attivato il flusso appropriato. Con `mid_al4_passkey` viene accettato esclusivamente un Passkey. Con `mid_al2_any` l'utente può scegliere tra Passkey, SIM, App o SMS. In caso di errori o Passkeys mancanti, la RP può consentire un [fallback](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback) sicuro su altri metodi. + + + +## Roadmap: il Mobile ID Passkey Vault + +Con il Mobile ID Passkey Vault, Mobile ID dispone di una soluzione in roadmap, attualmente in sviluppo, progettata per rendere possibile l'AAL3 con l'app Mobile ID. L'obiettivo è un authenticator che soddisfi i severi requisiti AAL3 e si collochi sullo stesso livello di sicurezza di una chiave hardware certificata FIPS, restando al contempo pienamente integrato nell'ecosistema Mobile ID. + +Rispetto alle chiavi hardware fisiche, il Passkey Vault offre chiari vantaggi operativi: il login Passkey può essere combinato direttamente con Geoblocking e consenso esplicito dell'utente, e l'authenticator può essere distribuito e scalato in modo molto più semplice ed economico rispetto a costosi token hardware. + +L'app Mobile ID evolve così in un authenticator software scalabile che completa l'autenticazione basata su SIM con MFA push-based, funzionalità Passkey e una UX nativa da smartphone più ricca per Transaction Signing e consenso utente. + +## Conclusione: tutto da un unico fornitore + +Con l'introduzione dei Passkeys, Mobile ID consolida la propria posizione come ecosistema unico che riunisce tutti i metodi di autenticazione rilevanti sotto un unico tetto. Passkeys per login browser resistenti al phishing. SIM per la massima sicurezza hardware senza installazione di app, incluso il Geofencing basato su rete mobile quando supportato. App per Geofencing GPS, biometria e utilizzo mondiale. Number Matching e Transaction Signing possono essere usati sia con SIM sia con App. E con l'Hybrid Auth Flow una soluzione che raggiunge un livello prossimo ad AAL3, senza che ogni utente debba possedere un token hardware. + +Le aziende beneficiano di un'integrazione OIDC standard, archiviazione dei dati in Svizzera e la sicurezza di un partner che impiega queste soluzioni internamente per proteggere infrastrutture altamente critiche. + +**Il cliente decide quale metodo si adatta meglio al proprio caso d'uso. Mobile ID offre la flessibilità necessaria.** + +*Mobile ID: il metodo giusto per ogni scenario. Tutto da un unico ecosistema.* + +Per domande sulle integrazioni Mobile ID, contattate [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). Per informazioni generali sul servizio, visitate [mobileid.ch](https://www.mobileid.ch/it). diff --git a/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.md b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.md new file mode 100644 index 0000000..daaa70c --- /dev/null +++ b/docs/release-notes/posts/2026-03-30-mobile-id-passkeys.md @@ -0,0 +1,227 @@ +--- +title: "Mobile ID Passkeys: Phishing-Resistant Authentication for Browser Scenarios" +date: 2026-03-30 +author: Mobile ID Team +description: "Passkeys enable phishing-resistant logins via biometrics in under 3 seconds. Mobile ID integrates them natively into the OIDC ecosystem and shows why SIM and App remain indispensable." +thumbnail: /release-notes/img/passkeys-thumb.png +lang: en +readingTime: 12 +layout: release-notes-post +--- + + + + + +
+Microsoft blocks roughly 7,000 password attacks per second every day, and 47% of consumers abandon a purchase when they forget their password. In a world where phishing remains the most common attack vector, a fundamentally new answer is needed. Passkeys are that answer. Mobile ID now integrates them natively into its OIDC ecosystem and combines them with the proven strengths of SIM and App. +
+ + + This explainer video was created with Google NotebookLM based on the Mobile ID article. + + +## NIST AAL and ISO/IEC LoA: Reference Frameworks for Security Levels + +Before examining each method in detail, a shared understanding of security levels is essential. In practice, two reference frameworks are commonly used: NIST SP 800-63B (now in revision 4) with three Authenticator Assurance Levels (AAL1-AAL3), and ISO/IEC 29115:2013 with four Levels of Assurance (LoA1-LoA4). Both describe the same underlying principle: how high the assurance and security level of an authentication is. What can be confusing is that the scales use different names and different numbering. The highest level is therefore either **AAL3** or **LoA4**, depending on which framework is being referenced. + +**AAL1** requires only single-factor authentication. Passwords, SMS OTPs or simple tokens satisfy this level. The security level is low. + +**AAL2** requires two different factors. In addition, a phishing-resistant option must be offered for online services. Cloud-synced Passkeys, TOTP generators, Mobile Push (such as Mobile ID SIM or App) and multi-factor OTP devices meet AAL2. + +**AAL3** is the highest NIST level. It requires phishing-resistant public-key cryptography with a non-exportable private key, along with stricter hardware, cryptographic and re-authentication requirements. Only a few authenticators fully meet these requirements: FIPS-certified security keys (e.g. YubiKey 5 FIPS Series), certain smartcards and hardware security modules. + +## What Are Passkeys? + +Passkeys are a user-friendly implementation of the FIDO2 standard and the WebAuthn API. They replace passwords with cryptographic key pairs and enable login via biometrics in under 3 seconds. The core principle: the private key never leaves the user's device. Instead, the authenticator signs a challenge that the server verifies with the public key. + +What makes Passkeys special is origin binding: the key is cryptographically bound to the domain of the service. Even if a user lands on a perfectly replicated phishing site, authentication fails because the browser detects the wrong domain and refuses to release the key. + +## Passkey Types: Convenience vs. Maximum Security + +Not all Passkeys are created equal. Different types are used depending on the level of protection required. The choice directly affects the achievable security level. + +### Cloud-Synced Passkeys + +Cloud-synced Passkeys are synchronized via the platform provider's cloud infrastructure: Apple iCloud Keychain, Google Password Manager or third-party managers such as 1Password. In mainstream consumer ecosystems, cloud synchronization has become the default user experience because it maximizes recovery and cross-device convenience. + +The major advantage: Passkeys are available across all devices within the same ecosystem. If a device is lost, access is retained through other devices. Synchronization uses end-to-end encryption. Cloud-synced Passkeys can also be shared with family members or friends, which also means they can end up on untrusted devices. + +Security level: **AAL2**. Since the keys are exportable and reside in cloud infrastructures (which are subject to the US CLOUD Act), they do not meet the requirements for AAL3. + +### Device-Bound Passkeys + +With device-bound Passkeys, the private key never leaves the security hardware. Typical examples are FIPS-certified security keys such as the YubiKey 5 FIPS Series (FIPS 140-2 Cert #3907, approx. CHF 100 at Digitec). These offer the highest security and are AAL3-compliant. + +Important to know: standard YubiKeys (without FIPS certification) are not sufficient for AAL3. In September 2024, a severe vulnerability was also discovered in the YubiKey 5 Series that cannot be fixed via firmware update but requires a physical replacement of the token. This illustrates a fundamental problem with physical tokens: security flaws can be expensive and cumbersome to resolve. + +Security level: **AAL3** (only with FIPS 140-2 certification and firmware 5.7 or newer). + +### Platform Authenticators + +Platform authenticators are security modules built directly into the device, such as Windows Hello (TPM), Apple Touch ID/Face ID (Secure Enclave) or the Titan M2 chip in Google Pixel devices. Depending on configuration, they can function as cloud-synced or device-bound. + +AAL3 is only achievable if the key is not synchronized to the cloud and the hardware component is FIPS-validated. In practice, this requires a device-bound configuration or an external authenticator that keeps the private key outside a cloud-synced credential store. + +### 3rd-Party Passkey Providers + +Since iOS 17 and Android 14, third-party providers can register as Passkey providers. The Credential Manager API (Android) and AuthenticationServices (iOS) allow authentication apps to create and manage Passkeys without relying on the system's built-in Passkey store. + +This is the technical foundation for the planned Mobile ID Passkey Vault: the Mobile ID App itself becomes a Passkey provider and can manage device-bound Passkeys at AAL3 level, without requiring physical hardware tokens. + +
+ Passkey types compared by security level: Cloud-Synced, Device-Bound and Platform Authenticators +
+ + + +## Passkey Integration: Simple for Users, Complex for Enterprises + +Passkeys promise a simple user experience. The technical reality behind the scenes, however, is demanding. A complete Passkey infrastructure requires: + +A **WebAuthn backend** with FIDO2 server library, attestation validation, credential management and secure key storage. A **credential lifecycle management** system for registration, deactivation, recovery and managing multiple Passkeys per user. **[Fallback mechanisms](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback)** for users without a Passkey-capable device or when authentication fails. **Compliance checks** for regulated industries, including [AAGUID validation](/oidc-integration-guide/passkey-authentication#rp-control-over-passkey-quality) against the FIDO Metadata Service (MDS) database and FIPS certification verification. + +Mobile ID resolves this complexity: Relying Parties do not integrate the Passkey infrastructure themselves but rather the Mobile ID OIDC Service. Passkey registration and management takes place centrally on mobileid.ch. A Passkey is registered once and can then be used across all connected Relying Parties. + +For enterprises, this means a standard OIDC integration with [configurable ACR values](/oidc-integration-guide/passkey-authentication#passkey-acr-values), automatic fallback to SIM, App or SMS, and the assurance of a partner like Swisscom that uses these solutions itself to protect highly critical infrastructures. + +## Security Profile by Usage Context + +All Mobile ID methods provide strong authentication. The optimal choice depends on the use case scenario. The key distinction: is this an open browser scenario with a freely chosen URL, or a closed journey? + +### Browser Journeys: Open URLs and Phishing Risk + +In the browser, the user navigates freely. They can click links in emails, type URLs manually or reach pages via search engines. This is where phishing risk is greatest: attackers can spoof domains and replicate login pages with near-perfect accuracy. + +Passkeys offer a systemic advantage in this scenario. Through cryptographic origin binding, the key is firmly tied to the authentic domain. The browser automatically checks whether the requesting domain matches the registered one. A phishing site on `m0bileid.ch` cannot access a Passkey registered for `mobileid.ch`. This makes Passkeys the first choice for pure web logins. + +Important: Passkeys are not free from attack vectors either. Malware on the platform, compromised browser extensions or social engineering at the operating system level can affect any method. Passkeys specifically eliminate the URL spoofing problem. + +### Closed Journeys: VPN, Remote Desktop, Kiosk, Native Apps + +For logins via VPN clients, remote desktop/VDI environments, kiosk terminals, native app-to-app transitions or helpdesk callbacks, other protection mechanisms apply. In these scenarios there is no freely chosen URL. The connection is controlled by the client or the infrastructure. URL spoofing is not an attack vector. + +Mobile ID SIM and App provide strong security here through hardware binding (EAL5+), number matching, transaction signing, and geofencing in supported scenarios. App-based geofencing uses GPS plus device-integrity signals; supported SIM geofencing uses mobile-network location data. Passkeys are often not usable in many of these scenarios: WebAuthn is a browser technology, and VPN clients or remote desktop sessions (no BLE channel to the authenticator!) frequently do not support them. + +### SIM and App Also Usable in the Browser + +SIM and App can also be used for browser logins. Not every use case requires maximum phishing resistance in the browser. For many applications, the proven push-based authentication via SIM or App is a pragmatic and secure solution. Mobile ID covers all scenarios with OIDC and REST API. + +
+ Authentication methods overview: Passkeys, SIM and App compared across scenarios +
+ +## Why SIM and App Remain Indispensable + +Passkeys are a strong addition for browser scenarios. SIM and App leverage their unique strengths where WebAuthn reaches its limits. + +### Mobile ID SIM + +The SIM-based method uses the Mobile ID enabled SIM card (or eSIM) as a secure hardware token. Over 6 million Swiss SIM cards from Swisscom, Sunrise, UPC and Salt are Mobile ID enabled. The cryptographic keys are stored directly on the SIM, which is certified under the protection profile **EAL5+** (ISO/IEC 15408) and Evaluation Level E3 (ITSEC). + +The SIM method requires no app installation and has no app store dependency. The authentication prompt is displayed as a SIM Toolkit overlay directly on top of the business application. It works on any mobile device, including devices without a smartphone operating system, and over the GSM channel. Via SMS-over-IP and WiFi, the SIM method is also usable when there is no cellular connection. + +When switching devices, the user simply moves the SIM. The account remains intact, without re-registration. SIM-based location verification is particularly trustworthy because the position within the mobile network is difficult to manipulate. + +### Mobile ID App + +The Mobile ID App (iOS and Android) offers, alongside biometric authentication, a broad range of app-specific advantages that cannot be replicated with Passkeys alone: + +**Push-based authentication** with biometrics or passcode as the second factor. **App-based geofencing** with GPS-based location determination and built-in jailbreak and mock service detection, making GPS spoofing more difficult. **Number matching and [transaction signing](/oidc-integration-guide/message-formats)** remain available across both Mobile ID SIM and Mobile ID App; on the App, they are combined with biometric approval and richer smartphone-native UX. **App-to-app transitions** enable automated switching between the business application and the Mobile ID App and back in banking scenarios. + +The app is based on technology from Futurae (ETH Zurich spin-off) and uses the device's Trusted Execution Environment (TEE). It is available worldwide in approved countries via the App Store. + +## Passkeys-Plus: The Hybrid Auth Flow for Near AAL3 + +NIST AAL3 is an extremely high security standard. True AAL3 requires, among other things, a FIPS 140-2 validated hardware module, which depends on the specific device configuration. For highly critical systems, Swisscom already uses the **Passkeys-Plus** model internally, which targets a very high security level. + +The approach combines two already existing components into a Hybrid Auth Flow: + +**Step 1: Cloud-Sync Passkey (AAL2).** The user authenticates in the browser with a Passkey. This provides broad ecosystem support and phishing-resistant origin binding. + +**Step 2: Mobile ID Push Step-Up.** The user then receives a push notification on their smartphone. Mobile ID Push uses public-key cryptography with non-exportable, device-bound keys. The user confirms with biometrics or passcode. Geoblocking and user consent display are optionally added. + +The combination delivers: origin-bound login plus device-bound, non-exportable key plus explicit user consent plus geolocation. This can reach AAL3 in deployments where the second factor runs on suitable FIPS 140-2 certified hardware. Whether it is recognized as full AAL3 in every regulatory context must still be assessed per use case, hardware basis and compliance framework. Broader FIPS-validated cryptography and device attestation coverage in the Mobile ID Push step will only be fully available after future enhancements. + +The push step remains on the smartphone. On desktop, the user authenticates locally with the Passkey, and the step-up occurs out-of-band via the phone. + +
+ Hybrid authentication for NIST AAL3: Cloud-Sync Passkey combined with Mobile ID Push Step-Up +
+ + + +## Mobile ID Authentication Levels: Granular Control via ACR Values + +Alongside these external reference frameworks, Mobile ID defines its own Authentication Levels (AL2-AL4) as ACR values in the [OIDC Authorization Request](/oidc-integration-guide/getting-started#authorization-code-request). These values determine which authentication methods are allowed for a given login. Mobile ID aligns this model with the four-level logic of ISO/IEC 29115. `AL4` therefore represents the highest Mobile ID security level. The full ACR matrix is documented in the [OIDC Integration Guide](/oidc-integration-guide/getting-started#authentication-context-class-reference-acr). + + + +In `mid_al4_passkey` mode, a Passkey-only authentication is enforced, guaranteeing true phishing resistance without weak fallbacks. For maximum flexibility, `mid_al2_any` allows all available methods including SMS. With `mid_al4_any`, Passkey authentication is preferred with a fallback to SIM or App. + +While most providers offer Passkeys only as a simple password replacement with insecure recovery paths (Google, PayPal, GitHub and even SBB allow OTP email as a fallback), Mobile ID enables the enforcement of strict security policies and the restriction to FIPS-certified authenticators via AAGUID validation against the FIDO Metadata Service database. + +## Registration and Login Flows + +The technical rollout is straightforward for Relying Parties. + +### Centralized Registration on mobileid.ch + +Users manage their Passkeys via the [MyMobileID Dashboard](/oidc-integration-guide/passkey-authentication#passkey-registration) on mobileid.ch/login. A new dashboard tile makes it immediately visible where Passkeys can be registered and maintained centrally. The Passkeys are stored on the domain m.mobileid.ch and are subsequently available across all connected Relying Parties. + +The new dashboard views highlight both the entry point and the central management experience at a glance: + + +

The Manage Passkeys tile is the central entry point for the new Passkey feature in MyMobileID. This is where users start registering and managing their Passkeys.

+
+ + +

Once opened, users see their already registered Passkeys in a clear management view and can expand or maintain their Passkey portfolio as needed.

+
+ + + +### RP Login via OIDC + +For typical login scenarios at a Relying Party, the dashboard now also includes the Mobile ID Check. It allows users to test their activated Mobile ID methods in a realistic authentication use case: + + +

The Mobile ID Check tile provides a simple entry point to test available Mobile ID methods such as SIM, App and now also Passkey directly from the dashboard.

+
+ + +

If at least one Passkey has already been registered, Passkey appears as a selectable method. This allows the new login option to be validated quickly in a typical [login flow](/oidc-integration-guide/passkey-authentication#authentication-flow-oidc) before productive use.

+
+ +Depending on the configured [ACR value](/oidc-integration-guide/passkey-authentication#passkey-acr-values), the appropriate flow is triggered. With `mid_al4_passkey`, only a Passkey is accepted. With `mid_al2_any`, the user can choose between Passkey, SIM, App or SMS. In case of errors or missing Passkeys, the RP can allow a secure [fallback](/oidc-integration-guide/passkey-authentication#passkey-only-vs-fallback) to other methods. + + + +## Roadmap: The Mobile ID Passkey Vault + +With the Mobile ID Passkey Vault, Mobile ID has a roadmap solution in development that is designed to enable AAL3 with the Mobile ID App. The aim is an authenticator that meets the stringent AAL3 requirements and operates on the same security level as a FIPS-certified hardware key, while remaining fully integrated into the Mobile ID ecosystem. + +Compared with physical hardware keys, the Passkey Vault offers clear operational advantages: passkey login can be combined directly with geoblocking and explicit user consent, and the authenticator can be rolled out and scaled far more easily and cost-effectively than expensive hardware tokens. + +The Mobile ID App thus evolves into a scalable software authenticator that complements SIM-based authentication with push-based MFA, passkey capabilities and a richer smartphone-native UX for transaction signing and consent. + +## Conclusion: Everything from a Single Source + +With the introduction of Passkeys, Mobile ID solidifies its position as a unique ecosystem that unites all relevant authentication methods under one roof. Passkeys for phishing-resistant browser logins. SIM for the highest hardware security without app installation, including supported mobile-network-based geofencing. App for GPS-based geofencing, biometrics and worldwide usability. Number matching and transaction signing can be used with both SIM and App. And with the Hybrid Auth Flow, a solution that achieves near AAL3 level without every user needing to own a hardware token. + +Enterprises benefit from a standard OIDC integration, Swiss data residency and the assurance of a partner that uses these solutions itself to protect highly critical infrastructures. + +**The customer decides which method best fits their use case. Mobile ID provides the flexibility to make it happen.** + +*Mobile ID: the right method for every scenario. Everything from one ecosystem.* + +For questions about Mobile ID integrations, reach out to [Backoffice.Security@swisscom.com](mailto:Backoffice.Security@swisscom.com). For general information about the service, visit [mobileid.ch](https://www.mobileid.ch/en). diff --git a/docs/rest-api-guide/app-provider-client-integration.md b/docs/rest-api-guide/app-provider-client-integration.md index b91e9fc..094686e 100644 --- a/docs/rest-api-guide/app-provider-client-integration.md +++ b/docs/rest-api-guide/app-provider-client-integration.md @@ -8,7 +8,7 @@ Before using the Swisscom Mobile ID web service, some initial provisioning steps 1. **The Mobile ID customer (your company) has an agreement with Swisscom:** - **Connectivity** (Internet or [EC](https://www.swisscom.ch/en/business/enterprise/offer/wireline/enterprise-connect.html)) between the **AP** and **Mobile ID** has been established. - - The customer has delivered the **X.509 client certificate** to Swisscom (see [Create X509 Client Certificates](/rest-api-guide/create-client-certs.md)). + - The customer has delivered the **X.509 client certificate** to Swisscom (see [Create X509 Client Certificates](/rest-api-guide/create-client-certs)). ::: warning Firewall Whitelisting The AP’s public source IP address (or range) must be whitelisted in the **Swisscom Firewall**. Contact Swisscom to request whitelisting. @@ -109,7 +109,7 @@ A certificate-based mutual authentication when accessing the Mobile ID web servi - Authentication is denied if the client sends a bag with the full certificate chain. - The Enhanced Key Usage value of client certificates must include Client Authentication (`1.3.6.1.5.5.7.3.2`). - - See **[Create X509 Client Certificates](/rest-api-guide/create-client-certs.md)** for examples of creating self-signed certificates. + - See **[Create X509 Client Certificates](/rest-api-guide/create-client-certs)** for examples of creating self-signed certificates. ::: danger All requests to the Mobile ID service must originate only from servers that you control. @@ -127,4 +127,3 @@ Get the root certificate from https://www.swisssign.com/en/support/faq.html - diff --git a/docs/rest-api-guide/best-practices.md b/docs/rest-api-guide/best-practices.md index 7ca554d..75e39f3 100644 --- a/docs/rest-api-guide/best-practices.md +++ b/docs/rest-api-guide/best-practices.md @@ -58,7 +58,7 @@ The key validation aspects are as follows: 2. **Validate the Mobile User’s X.509 Certificate** - Ensure the user certificate chains up to a trusted root CA contained in your local TrustStore. - The client should only trust certificates that link to a trust anchor matching the expected Swisscom Mobile ID CA. - - Your TrustStore should only contain the relevant root CA certificate (see **[Root CA Certificates](/rest-api-guide/root-ca-certs.md)**). + - Your TrustStore should only contain the relevant root CA certificate (see **[Root CA Certificates](/rest-api-guide/root-ca-certs)**). 3. **Verify the Digital Signature** - Confirm that the received digital signature is cryptographically valid. diff --git a/docs/rest-api-guide/imprint.md b/docs/rest-api-guide/imprint.md index a2a27bf..1dd1894 100644 --- a/docs/rest-api-guide/imprint.md +++ b/docs/rest-api-guide/imprint.md @@ -1,11 +1,8 @@ # Imprint -Mobile ID ist eine Marke von Swisscom.
-Swisscom (Schweiz) AG +This legacy page is kept for compatibility with existing guide links. -Sitz: Ittigen +The current legal information for `docs.mobileid.ch` is available here: -Postadresse:
-Swisscom (Schweiz) AG
-Alte Tiefenaustrasse 6
-CH-3050 Bern
\ No newline at end of file +- [Imprint](/legal/imprint) +- [Privacy Notice](/legal/privacy) diff --git a/docs/rest-api-guide/introduction.md b/docs/rest-api-guide/introduction.md index b9c017f..338e616 100644 --- a/docs/rest-api-guide/introduction.md +++ b/docs/rest-api-guide/introduction.md @@ -95,8 +95,10 @@ DTBD (DataToBeDisplayed) Classic View. -The App also supports Transaction Approval Style, which enhances readability by displaying -a title (type-field) and one or more key-value rows. +The App also supports a structured Transaction Approval Style, which enhances readability +by displaying a title (type-field) and one or more key-value rows. This presentation +format is App-specific. The broader capability to display and sign transaction data +exists with both SIM and App, while SIM uses the classic single-line DTBD format. =8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.55.1", - "@rollup/rollup-android-arm64": "4.55.1", - "@rollup/rollup-darwin-arm64": "4.55.1", - "@rollup/rollup-darwin-x64": "4.55.1", - "@rollup/rollup-freebsd-arm64": "4.55.1", - "@rollup/rollup-freebsd-x64": "4.55.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", - "@rollup/rollup-linux-arm-musleabihf": "4.55.1", - "@rollup/rollup-linux-arm64-gnu": "4.55.1", - "@rollup/rollup-linux-arm64-musl": "4.55.1", - "@rollup/rollup-linux-loong64-gnu": "4.55.1", - "@rollup/rollup-linux-loong64-musl": "4.55.1", - "@rollup/rollup-linux-ppc64-gnu": "4.55.1", - "@rollup/rollup-linux-ppc64-musl": "4.55.1", - "@rollup/rollup-linux-riscv64-gnu": "4.55.1", - "@rollup/rollup-linux-riscv64-musl": "4.55.1", - "@rollup/rollup-linux-s390x-gnu": "4.55.1", - "@rollup/rollup-linux-x64-gnu": "4.55.1", - "@rollup/rollup-linux-x64-musl": "4.55.1", - "@rollup/rollup-openbsd-x64": "4.55.1", - "@rollup/rollup-openharmony-arm64": "4.55.1", - "@rollup/rollup-win32-arm64-msvc": "4.55.1", - "@rollup/rollup-win32-ia32-msvc": "4.55.1", - "@rollup/rollup-win32-x64-gnu": "4.55.1", - "@rollup/rollup-win32-x64-msvc": "4.55.1", + "@rollup/rollup-android-arm-eabi": "4.60.0", + "@rollup/rollup-android-arm64": "4.60.0", + "@rollup/rollup-darwin-arm64": "4.60.0", + "@rollup/rollup-darwin-x64": "4.60.0", + "@rollup/rollup-freebsd-arm64": "4.60.0", + "@rollup/rollup-freebsd-x64": "4.60.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.0", + "@rollup/rollup-linux-arm-musleabihf": "4.60.0", + "@rollup/rollup-linux-arm64-gnu": "4.60.0", + "@rollup/rollup-linux-arm64-musl": "4.60.0", + "@rollup/rollup-linux-loong64-gnu": "4.60.0", + "@rollup/rollup-linux-loong64-musl": "4.60.0", + "@rollup/rollup-linux-ppc64-gnu": "4.60.0", + "@rollup/rollup-linux-ppc64-musl": "4.60.0", + "@rollup/rollup-linux-riscv64-gnu": "4.60.0", + "@rollup/rollup-linux-riscv64-musl": "4.60.0", + "@rollup/rollup-linux-s390x-gnu": "4.60.0", + "@rollup/rollup-linux-x64-gnu": "4.60.0", + "@rollup/rollup-linux-x64-musl": "4.60.0", + "@rollup/rollup-openbsd-x64": "4.60.0", + "@rollup/rollup-openharmony-arm64": "4.60.0", + "@rollup/rollup-win32-arm64-msvc": "4.60.0", + "@rollup/rollup-win32-ia32-msvc": "4.60.0", + "@rollup/rollup-win32-x64-gnu": "4.60.0", + "@rollup/rollup-win32-x64-msvc": "4.60.0", "fsevents": "~2.3.2" } }, diff --git a/package.json b/package.json index ec29738..c50c915 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "scripts": { "docs:dev": "vitepress dev docs", - "docs:build": "vitepress build docs", + "docs:build": "rm -rf docs/.vitepress/dist && vitepress build docs && node scripts/generate-legacy-redirects.mjs && node scripts/check-seo.mjs", + "docs:seo-check": "node scripts/check-seo.mjs", "docs:preview": "vitepress preview docs" }, "devDependencies": { diff --git a/scripts/check-seo.mjs b/scripts/check-seo.mjs new file mode 100644 index 0000000..57aa68d --- /dev/null +++ b/scripts/check-seo.mjs @@ -0,0 +1,208 @@ +import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs' +import path from 'node:path' + +const SITE_ORIGIN = 'https://docs.mobileid.ch' +const DIST_DIR = path.resolve('docs/.vitepress/dist') +const SITEMAP_PATH = path.join(DIST_DIR, 'sitemap.xml') +const ROBOTS_PATH = path.resolve('docs/public/robots.txt') +const SKIP_DIRS = new Set(['.git', 'node_modules', 'dist', 'cache']) +const LLMS_FILES = [ + path.resolve('docs/public/llms.txt'), + path.resolve('docs/public/llms-full.txt'), +] +const SOURCE_FILES = [ + ...walk(path.resolve('docs')).filter((filePath) => filePath.endsWith('.md')), + ...walk(path.resolve('docs/.vitepress')).filter((filePath) => /\.(?:mts|js|vue)$/.test(filePath)), +] +const REQUIRED_PATHS = [ + '/', + '/release-notes/', + '/rest-api-guide/', + '/oidc-integration-guide/', + '/radius-interface-gateway-guide/', +] + +if (!existsSync(DIST_DIR)) { + fail(`Missing build output at ${DIST_DIR}. Run "npm run docs:build" first.`) +} + +if (!existsSync(SITEMAP_PATH)) { + fail(`Missing sitemap at ${SITEMAP_PATH}.`) +} + +const builtPaths = buildAccessiblePathSet(DIST_DIR) +const errors = [] + +checkRobots() +checkRequiredPaths() +checkSitemap() +checkLlmsFiles() +checkInternalReferences() + +if (errors.length > 0) { + console.error('SEO check failed:') + for (const error of errors) { + console.error(`- ${error}`) + } + process.exit(1) +} + +console.log(`SEO check passed (${builtPaths.size} resolvable paths checked)`) + +function walk(rootDir) { + if (!existsSync(rootDir)) return [] + + const results = [] + for (const entry of readdirSync(rootDir, { withFileTypes: true })) { + const fullPath = path.join(rootDir, entry.name) + if (entry.isDirectory()) { + if (SKIP_DIRS.has(entry.name)) continue + results.push(...walk(fullPath)) + } else if (entry.isFile()) { + results.push(fullPath) + } + } + return results +} + +function fail(message) { + console.error(message) + process.exit(1) +} + +function toPosix(filePath) { + return filePath.split(path.sep).join(path.posix.sep) +} + +function normalizeSitePath(input) { + if (!input) return null + + let value = input.trim() + if (!value) return null + if (value.startsWith(SITE_ORIGIN)) { + value = new URL(value).pathname + } + + if (!value.startsWith('/')) return null + if (value.startsWith('//')) return null + + value = value.split('#')[0].split('?')[0] + if (!value) return '/' + return value +} + +function buildAccessiblePathSet(distDir) { + const accessiblePaths = new Set() + const files = walk(distDir) + + for (const filePath of files) { + const relativePath = toPosix(path.relative(distDir, filePath)) + const stat = statSync(filePath) + if (!stat.isFile()) continue + + if (relativePath.endsWith('.html')) { + const basename = path.posix.basename(relativePath) + if (basename === 'index.html') { + const dir = path.posix.dirname(relativePath) + const webPath = dir === '.' ? '/' : `/${dir}/` + accessiblePaths.add(webPath) + accessiblePaths.add(`/${relativePath}`) + if (webPath !== '/') { + accessiblePaths.add(webPath.slice(0, -1)) + } + } else { + accessiblePaths.add(`/${relativePath}`) + accessiblePaths.add(`/${relativePath.slice(0, -5)}`) + } + continue + } + + accessiblePaths.add(`/${relativePath}`) + } + + return accessiblePaths +} + +function checkRobots() { + const robotsTxt = readFileSync(ROBOTS_PATH, 'utf8') + if (!/Sitemap:\s+https:\/\/docs\.mobileid\.ch\/sitemap\.xml/.test(robotsTxt)) { + errors.push('docs/public/robots.txt must point to https://docs.mobileid.ch/sitemap.xml') + } +} + +function checkRequiredPaths() { + for (const requiredPath of REQUIRED_PATHS) { + if (!builtPaths.has(requiredPath)) { + errors.push(`Required public path does not resolve in dist: ${requiredPath}`) + } + } +} + +function checkSitemap() { + const sitemapXml = readFileSync(SITEMAP_PATH, 'utf8') + const matches = [...sitemapXml.matchAll(/(.*?)<\/loc>/g)] + if (matches.length === 0) { + errors.push('sitemap.xml contains no entries') + return + } + + for (const match of matches) { + const url = match[1] + const pathname = normalizeSitePath(url) + if (!pathname) continue + + if (!builtPaths.has(pathname)) { + errors.push(`Sitemap URL does not resolve in dist: ${url}`) + } + } +} + +function checkLlmsFiles() { + for (const filePath of LLMS_FILES) { + const fileLabel = path.relative(process.cwd(), filePath) + const text = readFileSync(filePath, 'utf8') + const urls = new Set( + [...text.matchAll(/https:\/\/docs\.mobileid\.ch[^\s)"'<>,]*/g)] + .map((match) => match[0].replace(/[.]+$/, '')), + ) + + for (const url of urls) { + const pathname = normalizeSitePath(url) + if (!pathname) continue + + if (!builtPaths.has(pathname)) { + errors.push(`${fileLabel} references a non-resolving docs URL: ${url}`) + } + } + } +} + +function checkInternalReferences() { + const patterns = [ + /\[[^\]]*]\((\/[^)\s]+)\)/g, + /\b(?:href|src)=["'](\/[^"']+)["']/g, + /\blink:\s*['"](\/[^'"]+)['"]/g, + /url\((['"]?)(\/[^)'"]+)\1\)/g, + ] + + for (const filePath of SOURCE_FILES) { + const fileLabel = path.relative(process.cwd(), filePath) + const text = readFileSync(filePath, 'utf8') + const references = new Set() + + for (const pattern of patterns) { + for (const match of text.matchAll(pattern)) { + references.add(match[1] ?? match[2]) + } + } + + for (const reference of references) { + const pathname = normalizeSitePath(reference) + if (!pathname) continue + + if (!builtPaths.has(pathname)) { + errors.push(`${fileLabel} references a non-resolving internal path: ${reference}`) + } + } + } +} diff --git a/scripts/generate-legacy-redirects.mjs b/scripts/generate-legacy-redirects.mjs new file mode 100644 index 0000000..9f4fe6f --- /dev/null +++ b/scripts/generate-legacy-redirects.mjs @@ -0,0 +1,137 @@ +import { mkdirSync, writeFileSync } from 'node:fs' +import path from 'node:path' + +const DIST_DIR = path.resolve('docs/.vitepress/dist') + +const redirects = new Map() + +function addRedirect(from, to) { + redirects.set(from, to) +} + +function addSectionRedirects(fromBase, toBase, entries) { + for (const entry of entries) { + const [fromSlug, toSlug = fromSlug] = Array.isArray(entry) ? entry : [entry, entry] + addRedirect(`${fromBase}/${fromSlug}`, `${toBase}/${toSlug}`) + } +} + +addSectionRedirects('/reference-guide', '/rest-api-guide', [ + 'app-provider-client-integration', + 'auto-activation', + 'best-practices', + 'create-client-certs', + 'health-status', + 'imprint', + 'introduction', + 'mobile-id-api', + 'root-ca-certs', + 'status-fault-codes', +]) + +addSectionRedirects('/oidc', '/oidc-integration-guide', [ + 'best-practices', + 'cloud-integration-guide', + 'getting-started', + 'imprint', + 'introduction', + 'message-formats', + 'oidc-use-cases', +]) + +addSectionRedirects('/rig-radius', '/radius-interface-gateway-guide', [ + 'annexes', + 'introduction', + 'radius-protocol', + ['rig-deployment', 'deployment'], +]) + +addSectionRedirects('/entraid', '/oidc-integration-guide', [ + ['external-auth-methods', 'cloud-integration-guide#microsoft-entra-id'], + ['getting-started', 'cloud-integration-guide#microsoft-entra-id'], + ['imprint', 'cloud-integration-guide#microsoft-entra-id'], + ['troubleshooting', 'cloud-integration-guide#troubleshooting'], +]) + +addSectionRedirects('/entraid-guide', '/oidc-integration-guide', [ + ['external-auth-methods', 'cloud-integration-guide#microsoft-entra-id'], + ['getting-started', 'cloud-integration-guide#microsoft-entra-id'], + ['imprint', 'cloud-integration-guide#microsoft-entra-id'], + ['troubleshooting', 'cloud-integration-guide#troubleshooting'], +]) + +addRedirect('/api-reference/api', '/rest-api-guide/api-specification') +addRedirect('/api-reference/openapi-explorer', '/rest-api-guide/api-specification') +addRedirect('/api-reference/mermaid-demo', '/') +addRedirect('/api/', '/rest-api-guide/api-specification') +addRedirect('/api/api', '/rest-api-guide/api-specification') +addRedirect('/rest-api-guide/', '/rest-api-guide/introduction') +addRedirect('/oidc-integration-guide/', '/oidc-integration-guide/introduction') +addRedirect('/radius-interface-gateway-guide/', '/radius-interface-gateway-guide/introduction') +addRedirect('/reference-guide/application-integration', '/rest-api-guide/app-provider-client-integration') +addRedirect('/reference-guide/release-notes', '/release-notes/') +addRedirect('/oidc/coud-integration-guide', '/oidc-integration-guide/cloud-integration-guide') +addRedirect('/radius-interface-gateway-guide/rig-deployment', '/radius-interface-gateway-guide/deployment') +addRedirect('/release-notes/release-notes', '/release-notes/') +addRedirect('/blog/', '/release-notes/') +addRedirect('/blog/posts/2026-03-23-mobile-id-passkeys', '/release-notes/posts/2026-03-30-mobile-id-passkeys') + +for (const langSuffix of ['', '.de', '.fr', '.it']) { + addRedirect( + `/release-notes/posts/2026-03-23-mobile-id-passkeys${langSuffix}`, + `/release-notes/posts/2026-03-30-mobile-id-passkeys${langSuffix}`, + ) + addRedirect( + `/release-notes/posts/2026-03-28-mobile-id-entra-external-mfa${langSuffix}`, + `/release-notes/posts/2026-03-27-mobile-id-entra-external-mfa${langSuffix}`, + ) +} + +function renderRedirectHtml(targetPath) { + const escapedTarget = targetPath + .replaceAll('&', '&') + .replaceAll('"', '"') + + return ` + + + + Redirecting… + + + + + + +

This page has moved to ${escapedTarget}.

+ + +` +} + +function writeRedirectFile(relativeFilePath, targetPath) { + const fullPath = path.join(DIST_DIR, relativeFilePath) + mkdirSync(path.dirname(fullPath), { recursive: true }) + writeFileSync(fullPath, renderRedirectHtml(targetPath)) +} + +for (const [fromPath, toPath] of redirects) { + const normalizedFrom = fromPath === '/' ? '/' : fromPath.replace(/\/+$/, '') + + if (fromPath.endsWith('/')) { + writeRedirectFile(path.posix.join(normalizedFrom.slice(1), 'index.html'), toPath) + continue + } + + if (normalizedFrom.endsWith('.html')) { + writeRedirectFile(normalizedFrom.slice(1), toPath) + continue + } + + writeRedirectFile(`${normalizedFrom.slice(1)}.html`, toPath) + writeRedirectFile(path.posix.join(normalizedFrom.slice(1), 'index.html'), toPath) +} + +console.log(`Generated ${redirects.size} legacy redirect mappings in ${DIST_DIR}`)