<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Iam on Robin&#39;s notebook</title>
    <link>https://notes.robinvanhove.me/tags/iam/</link>
    <description>Recent content in Iam on Robin&#39;s notebook</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Wed, 04 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://notes.robinvanhove.me/tags/iam/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>FOSDEM 2026 Day 1</title>
      <link>https://notes.robinvanhove.me/posts/2026/fosdem-1/</link>
      <pubDate>Wed, 04 Feb 2026 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/posts/2026/fosdem-1/</guid>
      <description>&lt;p&gt;This post contains the notes that I took during FOSDEM 2026. The big new topics
this year seemed to be on AI &amp;amp; digital sovereignty. But off course the
main subject matter of the conference will always be &lt;del&gt;beer&lt;/del&gt; open source.&lt;/p&gt;
&lt;p&gt;The following notes are some ramblings combining what the speakers said and
thoughts I had while listening. I took them for future references and decide to
publish them because 🤷 why not.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>This post contains the notes that I took during FOSDEM 2026. The big new topics
this year seemed to be on AI &amp; digital sovereignty. But off course the
main subject matter of the conference will always be <del>beer</del> open source.</p>
<p>The following notes are some ramblings combining what the speakers said and
thoughts I had while listening. I took them for future references and decide to
publish them because 🤷 why not.</p>
<p><a href="/posts/2026/fosdem-2">Notes on day 2</a>.</p>
<h2 id="stands">Stands</h2>
<p>It&rsquo;s always fun to see the myriad of OSS projects having a stand at FOSDEM.
After coming here a few years I had seen most of them already so I did not
spend too much time browsing around. I did make sure that a picked up some
stickers off course!</p>
<p>I did learned about <a href="https://www.privacyidea.org/">privacyidprivacyIDEA</a> &ldquo;a
modular authentication server&rdquo;. Honestly I am not exactly certain what it is,
it&rsquo;s not an Idp like <a href="/notes/keycloak">keycloak</a> but focusses only on
<a href="/notes/mfa">MFA</a>. It seems like way to centrally mange (hardware) tokens &amp;
keys for organisations.</p>
<p>The radio amateurs had an interesting stand as always and I was reminded that
<a href="https://hamcon.be/">hamcon</a> will take place later this year.</p>
<h2 id="main-track-on-desktops">Main track on desktops</h2>
<p><img loading="lazy" src="/posts/2026/fosdem-1/grandma.jpeg" type="" alt="Speaker with a slide that says My grandma is now a Linux user"  />
<em>Picture actually taken on day 2.</em></p>
<h3 id="wayland-compositors-for-fun-and-profit">Wayland compositors for fun and profit</h3>
<p>Turns out that building a wayland compositor can be fun and apparently <em>easy</em>
because of existing rust libraries. Wayland can even work on the small screen
of the <a href="https://www.turris.com/en/">Turris opeon source router</a>.</p>
<h3 id="kde-at-30-still-looking-ahead">KDE at 30: Still looking ahead</h3>
<p>🤔 <em>I have always loved the KDE destkop, but I keep switching between KDE &amp;
GNOME (at the time of writing I&rsquo;m on GNOME). Maybe I should consider switching
again, and maybe trye NixOS as a desktop distro.</em></p>
<p>I learned some new things such as that KDE started in Germany and KHTML started
as a KDE project and became webkit over time, which is now used a lot by Apple.</p>
<p>KDE hardware: Slimbooks, Steamdeck.</p>
<p>End of 10 campaign: not all old Windows 10 devices need to be thrown away.</p>
<p>Plsame mobile 6: Difficult to install on mobile because of protected hardware.
Some new device called <a href="https://mecha.so/">Mecha</a>?</p>
<p>Plasma bigscreen is still a thing.</p>
<h3 id="linux-on-the-desktop--why-digital-sovereignty-starts-here">Linux on the Desktop – Why Digital Sovereignty Starts Here</h3>
<p>For organisations that we work with/for it&rsquo;s important to achieve digital
sovereignty. To avoid price gauging, to have freedom of choice and
decentralization.</p>
<p>Linux Client Management: Foreman, Config management (SaltStack, Ansible, &hellip;),
GitOps.</p>
<p>OpenDesk: Zendis (German government digital sovereignty agency) office suite.
Existing FOSS tools such as Univention for Identity management and Nordeck for
video conferencing.</p>
<p>An EU OS?</p>
<p>Securing enterprise linux: antivirus &amp; disabeling USB device access.</p>
<p>🤔 <em>IS ClamAV actually usefull on a linux desktop? Becasue AFAIK it mostly
searches for fingerprints of windows viruses.</em></p>
<p>Challenging to integrate with proprietary software. No fully sovereign solution
at the moment.</p>
<p>Immutable OS is nice to have: Secure, easy to manage.</p>
<p>Sovereign IDM, Himmelblau from samba: seamless Azure Entra ID and Intune
integration for Linux.</p>
<h2 id="security-devroom">Security Devroom</h2>
<h3 id="all-your-keybaords-are-belong-to-us">All your keybaords are belong to us</h3>
<p>Van Eck phreaking: signal leakage, live demonstraion on the BBC youtube: BBC
tempest, skip the shakespeare part demo of stealing contents of PC monitor.</p>
<p>Tempest: A signal problem</p>
<p>Books: Spy Catcher &amp; The SPY in Moscow station.</p>
<p>Type writer noise can be used to determine text, soundproofiing help the
attacker: improving signal to noise ratio.</p>
<p>Skype-Type: Keyboard acoustisc eavesdropping tool during call. Nowdays
difficult due too noise filters.</p>
<p>Markus G. Kuhm: Large paper on emissions</p>
<p>Recording of the rest of the talk on DEFFCON.</p>
<h3 id="the-invisible-key-securing-the-new-attack-vector-of-oauth-tokens">The invisible key: Securing the new attack vector of OAuth tokens</h3>
<blockquote>
<p>Hackers don&rsquo;t break in, they login.</p>
<p>&ndash; <em>Corey Nachreiner (probably)</em></p>
</blockquote>
<p>You can&rsquo;t apply conditional access to tokens. 🤔 <em>Is that not what the <a href="/notes/openid_ssf">Shared
signals framework</a> tries to solve?</em></p>
<p>Five major conserns:</p>
<ul>
<li>Longevity of token and forgotten access</li>
<li>Scope / privilege creep</li>
<li>Supply chain risk: the domino effect</li>
<li>Token leakage</li>
<li>Revocation gaps and off boarding failure, Off boarding a user does not mean
off boarding a token.</li>
</ul>
<p>Common attack vectors such as during the attack on salesforce. By Gangs:
Scattered spider, ShinyHunters. Attacks still often involve social engineering.</p>
<p>How to avoid: Audit <a href="/notes/oauth">OAuth</a> Apps, Centralize logs, use canary
tokens</p>
<p>Stop granting overprivileged permissions to applications.</p>
<p>Conditional access requires support on the browser?
(🤔 <em>not sure what the speaker meant with this</em>).</p>
<p>Use mTLs for certificate bound client credentials flow or DPoP.</p>
<p>IPSIE, which is the OpenID working group tackeling shared signals.</p>
<h3 id="dynamic-bot-blocking-with-web-server-access-log-analytics">Dynamic Bot Blocking with Web-Server Access-Log Analytics</h3>
<p>You don&rsquo;t have to use cloudflare for bot detection.</p>
<p>Tempest-tech.com</p>
<p>DDOS prectection &amp; Web security</p>
<p>Fingerprinting of user agents: JA3/JA4, p0f, tempest.</p>
<p>Log shipping to clickhouse.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>FOSDEM 2026 Day 2</title>
      <link>https://notes.robinvanhove.me/posts/2026/fosdem-2/</link>
      <pubDate>Wed, 04 Feb 2026 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/posts/2026/fosdem-2/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://notes.robinvanhove.me/posts/2026/fosdem-1&#34;&gt;Notes on day 1&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;identity-and-access-management-devroom&#34;&gt;Identity and Access Management Devroom&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This room is cursed.&lt;/p&gt;
&lt;p&gt;&amp;ndash; &lt;em&gt;The video volunteer when entering the room in the morning.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Day two stared of great with a some great presentations in the IAM devroom. I
woke up early so I could get a seat on the front row and was happy that I did.&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://notes.robinvanhove.me/posts/2026/fosdem-2/thomas.jpg&#34; type=&#34;&#34; alt=&#34;Thomas Darimont giving a presentation on OpenID&amp;rsquo;s shared signals framework.&#34;  /&gt;
&lt;em&gt;Thomas Darimont giving a presentation on OpenID&amp;rsquo;s shared signals framework.&lt;/em&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="/posts/2026/fosdem-1">Notes on day 1</a></p>
<h2 id="identity-and-access-management-devroom">Identity and Access Management Devroom</h2>
<blockquote>
<p>This room is cursed.</p>
<p>&ndash; <em>The video volunteer when entering the room in the morning.</em></p>
</blockquote>
<p>Day two stared of great with a some great presentations in the IAM devroom. I
woke up early so I could get a seat on the front row and was happy that I did.</p>
<p><img loading="lazy" src="/posts/2026/fosdem-2/thomas.jpg" type="" alt="Thomas Darimont giving a presentation on OpenID&rsquo;s shared signals framework."  />
<em>Thomas Darimont giving a presentation on OpenID&rsquo;s shared signals framework.</em></p>
<h3 id="an-introduction-to-the-openid-shared-signals-framework">An Introduction to the OpenID Shared Signals Framework</h3>
<p>SSF tries to normalize the signals to do Continuous Access Evaluation</p>
<p>Use Cases:</p>
<ol>
<li>Real-time Session Revocation</li>
<li>Compromsed Account Alert</li>
<li>Automated User Deprovisioning</li>
</ol>
<p>Building blocks: Security Event, Transmitter (System emitting event), Receiver,
Stream and subscription on events. Security Event tokens are an IETF RFC</p>
<p>Profiles: Set of use cases and events</p>
<ul>
<li>CAEP
<ul>
<li>Based on sessions</li>
<li>Evalutaion of access decisions</li>
</ul>
</li>
<li>RISC
<ul>
<li>disaster mitigation</li>
<li>security risks and inicdnets</li>
</ul>
</li>
</ul>
<p>Delivery methods are push (RFC 8935) or poll (RFC 8936).</p>
<p>There is also an IETF draft for SCIM Events.</p>
<p><a href="htps://caep.dev">htps://caep.dev</a></p>
<p>Implementation in Keycloak with pull request 43950 Custom login when receiving
events. Next step will be transmitter support.</p>
<h4 id="questions--thoughts-">Questions &amp; thoughts 🤔</h4>
<ul>
<li>Does the CAPE profile make OpenID connect session managment obsolete?
<ul>
<li>Answer: No, different use cases</li>
</ul>
</li>
<li>For SaaS, how is privacy of the user handled?</li>
<li>In Keycloak is the logic on how to handle events configurable, if so how?</li>
</ul>
<h3 id="nextcloud-as-identity-provider-scim-client-integration-for-multi-platform-collaboration">Nextcloud as Identity Provider? SCIM Client Integration for Multi-Platform Collaboration</h3>
<p>Nextcloud X OpenProject</p>
<p>Use scim for automated identity information exchange.</p>
<p>AGPLv3: The only sensible license option for NC apps according to the speaker .</p>
<h4 id="questions--thoughts--1">Questions &amp; thoughts 🤔</h4>
<ul>
<li>Why not use a dedicated IDP?</li>
</ul>
<p>Now I am a bit confused on what exactly the difference is between the SCIM client and server.
I should do a deep div on <a href="/notes/scim">SCIM</a>.</p>
<h3 id="keeping-applications-secure-by-evolving-oauth-20-and-openid-connect">Keeping applications secure by evolving OAuth 2.0 and OpenID Connect</h3>
<p>FAPI 2.0 was published in 2025 targeting more than just banking (e-health, government).</p>
<p>Security assumptions of FAPI 2.0 were well documented.</p>
<p><a href="https://openid.net/specs/fapi-attacker-model-2_0-final.html">https://openid.net/specs/fapi-attacker-model-2_0-final.html</a></p>
<p>Secure your transport layer!</p>
<ul>
<li>TLS 1.2+</li>
<li>Check certificates</li>
<li>DNSSEC</li>
<li>Secure ciphers</li>
<li>HTSTS</li>
</ul>
<p>OAuth best pratices</p>
<ul>
<li>TLS on all endpoints</li>
<li>No ROPC</li>
<li>No wildcards in redirct URIs</li>
<li>Private key JWT client authentication (no public clients)</li>
<li>Pushed Auth. request (PAR)</li>
<li>PKCE with S256</li>
<li>Sender contrained tokesn (mTLS or DPoP)</li>
</ul>
<p>An API can respond to a API request with a DPoP nonce request. Adding an extra
step to an API request, but improving security.</p>
<p>🤔 I wonder if this is always required for DPoP or if the nonce is optional.
The RFC says <em>&ldquo;An authorization server MAY supply a nonce value to be included
by the client in DPoP proofs sent.&rdquo;</em> So I guess it&rsquo;s optional. See <a href="https://datatracker.ietf.org/doc/html/rfc9449#name-authorization-server-provid">RFC
9449</a>
for details.</p>
<p>Keycloak has builtin client profiles. Which enforces security requirements on
clients. Enforced at config and runtime. Rules can be added to a custom
profile.</p>
<p>Funny way to convince development teams to keep clients secure: brownouts to
speed up the process. Security with a whip!</p>
<p>There is a <a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/co-located-events/keycloakcon/#about">keycloak
conference</a>
taking place in Amsterdam in March 2026.</p>
<h4 id="questions--thoughts--2">Questions &amp; thoughts 🤔</h4>
<p>Error messages in the Keycloak admin UI suck. This could be something that can
be improved by the community. If I felt more comfortable with the codebase I
could pick it up.</p>
<p>I wonder if the security profiles could be externalised, I have built scripts
in the past to validate OAuth client configs against a set of security rules.</p>
<h3 id="inside-proconnect-building-a-modern-federated-identity-provider-for-government-services">Inside ProConnect: Building a Modern Federated Identity Provider for Government Services</h3>
<p>ProConnect enables single login for grench government services (public
servants, external users)</p>
<p>La Suite numerique a set of open source tools provided by the French Govt.</p>
<p>Demo with one of the best: Visio for vidio confernces.</p>
<ul>
<li>User gives email and ProConnect redirect to the correct underlying IDP.</li>
<li>The designs of the webui&rsquo;s are alligned.</li>
</ul>
<p>From FranceConnect to ProConnect</p>
<p>Proconnect has ~40 Idp&rsquo;s!</p>
<p>SP &amp; Idp Mocks.</p>
<p><a href="http://www.dev-agentconnect.fr/">http://www.dev-agentconnect.fr/</a></p>
<p>Identity borkering: Email domain name based routing.</p>
<p>Passkey auht with AMR POP</p>
<p>Identity format for public servants in a professional context.</p>
<p>Testing is free via Espace Parenaires.</p>
<p>Easy install of ProConnect with Docker.</p>
<p>Open Repository on github</p>
<h4 id="questions--thoughts--3">Questions &amp; thoughts 🤔</h4>
<ul>
<li>If ProConnect is a fork of FranceConnect, is the infra / user database / &hellip; also forked?</li>
<li>IF ProConnect acts as an Identity Broker, how does it decide on the Idp to user?
<ul>
<li>Is the user identified first?
<ul>
<li>Yes, map of email domains to Idp.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="privacy-and-sovereignty-in-a-post-quantum-open-world">Privacy and Sovereignty in a Post Quantum Open World</h3>
<p>Kings &amp; Serfs, Masers &amp; Slaves. Closed source users are software slaves!</p>
<p>Business people hat the word freedom (Choice, competition)</p>
<p>Sovereignty, not just for data but: Software, Networking, Technology.</p>
<p>Users need to control</p>
<p>One more consideration: Quantum Computing</p>
<ul>
<li>(re)encrypt data</li>
<li>VPN&rsquo;s -&gt; QPN&rsquo;s</li>
<li>Need to move towards MFA</li>
</ul>
<p>We need a community of trusted people.</p>
<ul>
<li>Freedom Software</li>
<li>RISC-V Architecture
<ul>
<li>Now moved to swiss</li>
</ul>
</li>
</ul>
<p>We need sovereign cloud that are security first.</p>
<p>Corporta: Secure sentinel</p>
<p>Community cloud: freedombox.org</p>
<p>Tiny server on SBC.</p>
<p>Also supports fediverse.party software for social networks.</p>
<p>MFA: Hardwayre keys: need to use 2.
Has to be open design:</p>
<ul>
<li>inspectable</li>
<li>long life</li>
</ul>
<p>Working with <a href="https://solokeys.com">solokeys</a> an open-source FIDO2 security key.</p>
<h3 id="suseid---sovereign-iam-at-suse">SUSEID - Sovereign IAM at SUSE</h3>
<p>How suse has tackled IAM landscape.</p>
<p>Lot&rsquo;s of mergers: Multiple password providers, add-ons and bridges.</p>
<p>The ride for an average SUSE Employee</p>
<ul>
<li>Open Jira: user +pass</li>
<li>Open conflunece: user +pass</li>
<li>Open build service: user +pass</li>
<li>Bugziall: user +pass</li>
<li>suse costuomer center: different prompt!</li>
</ul>
<p>Art21 of nis2
Dora art 5,9,10</p>
<p>-&gt; No SaaS for Auth.</p>
<p>Self hosting comes with costs, (ops, dc, &hellip;)</p>
<p>Patroni for HA PostgreSQL
Garage for obj storage</p>
<p>Authentik IDP</p>
<p>Existing projects: smallstep KanIDM</p>
<p>New projects:</p>
<ul>
<li>stepdance: certifiactes</li>
<li>ldap SEBIN search + bind</li>
<li>IDM Merge: Idm Aggregator &amp; Dedup</li>
</ul>
<h3 id="credentials-for-linux-bringing-passkeys-to-the-linux-desktop">Credentials for Linux: Bringing Passkeys to the Linux desktop</h3>
<p>Passkeys are quite complex.</p>
<p>Passkey = FIDO2 discoverable credential</p>
<ul>
<li>usernamesless &amp; passwordless</li>
</ul>
<p>New FIDO2</p>
<ul>
<li>Hybrid flow: Passkey on pohne (qr code)</li>
<li>synced Passkeys</li>
</ul>
<p>Modern Passkeys</p>
<p>Phones and password managers
Default:</p>
<ul>
<li>Google Password manager</li>
<li>iCloud keychain
Third party:</li>
<li>bitwaden</li>
<li>oss</li>
</ul>
<p>requires credential provider API</p>
<p>(synced creendials)</p>
<p>Security keys still for entrprise</p>
<p>Linux desktop needs platform api&rsquo;s.</p>
<p>Inconsistent api: currently apps (browsers) implement UX themselves.</p>
<p>Containerized (flatpak) apps&rsquo; don&rsquo;t have access to hardware api&rsquo;s (workaround
<code>--device=all</code>, enables origin bypass)</p>
<p>Solution: a new Credentials api.</p>
<ul>
<li>D-Bus</li>
<li>support for privileged and unprvilegd clients</li>
</ul>
<p>New componenents:</p>
<ul>
<li>lebwebauthn: CTAP/WebAuthn</li>
<li>credentialsd</li>
</ul>
<p>Use of xdg-desktop portals for sandboxed apps.</p>
<p>In libauthn: TPM 2.0 (platform) is planned</p>
<p>Open Cahllenges:</p>
<ol>
<li>Origin scoping: credentials for your origin should only be accessed by that origin.</li>
</ol>
<ul>
<li>How do we determine origin</li>
</ul>
<ol start="2">
<li>App identity verification?</li>
</ol>
<p>Prividleged: any origin (browsers)
unprvilegd: restricted to specific origin</p>
<h3 id="cockpit-and-passwordless-login">Cockpit and passwordless login</h3>
<p>Cockpit authentication:</p>
<ul>
<li>Preferably PAM modules</li>
<li>SSO, Kerberos, &hellip;</li>
<li>Flatpak app</li>
</ul>
<p>SSH keys are an example of passwordless but not usable in te browser.</p>
<p>Based on WebAuthn,FIDO2,Passkeys</p>
<ul>
<li>ensure origin authenticity</li>
<li>web domain / hostname / realm differences.</li>
<li><code>/.well-known-webauthn</code>
<ul>
<li>Can support multiple origins.</li>
</ul>
</li>
</ul>
<p>Registering with the &ldquo;Chromium virtual authenticator enviroment&rdquo; for testing / demo.</p>
<p>Passkey</p>
<ul>
<li>Discoverable</li>
<li>limited slots</li>
<li>no username needed, user</li>
<li>Non-discoverable
<ul>
<li>doesn&rsquo;t store on hardware</li>
</ul>
</li>
</ul>
<h4 id="questions--thoughts--4">Questions &amp; thoughts 🤔</h4>
<p>I should look further into discoverable vs Non-discoverable credentials on <a href="/notes/passkeys">passkeys</a>.</p>
<p>Fancy slides! I wonder what was used to create them.</p>
<h3 id="passwordless-authentication-mechanisms-from-the-gui-gdm">Passwordless authentication mechanisms from the GUI (GDM)</h3>
<p>GDM: Login on gnome (Password, Smartcard, Fingerprint)</p>
<p>Gnome shell renders the UI. Runs as GDM user To authenticate GDM calls PAM over
private dbus servers.</p>
<p>Improved UX: select auth. method.</p>
<p>New web login with OAuth device code flow.</p>
<p>Fingerprint only on lock screen.</p>
<p>Available in SSSD 2.12.0</p>
<p>Two merge requests for GNOME 50</p>
<p>Future enhancements:</p>
<ul>
<li>embedded webview</li>
<li>PAM conversation through fd</li>
<li>Move GDM into systemd?</li>
</ul>
<h4 id="questions--thoughts--5">Questions &amp; thoughts 🤔</h4>
<p>Someone asked a question on using <a href="/notes/SPIFFE">SPIFFE</a> which is used for
workload authentication, I guess they were wondering if it&rsquo;s possible to let an
AI agent authenticate to a Linux machine with a gnome desktop this way?</p>
<h3 id="reduce-attack-surface-or-keep-compatibility-lessons-of-sudo-rs-and-run0-transition-plans">Reduce attack surface or keep compatibility: lessons of sudo-rs and run0 transition plans</h3>
<p>US Govt. mandating secure software</p>
<ul>
<li>Zero trust</li>
<li>Secure software development</li>
<li>Switch to modern languages</li>
</ul>
<p>Will take long time to transition (ZTA, Post-Quantum).</p>
<p>How to reduce attack surface?</p>
<ul>
<li>run0 aims for a system without SUID</li>
<li>polkit for AuthZ</li>
</ul>
<h4 id="reducing-attack-surface">Reducing attack surface</h4>
<p>Sudo-rs: Switching to Rust</p>
<ul>
<li>Memory safety</li>
<li>Thread safety</li>
<li>Error handling</li>
<li>Strong typing</li>
</ul>
<h4 id="large-scale-deployments">Large scale deployments</h4>
<p>FreeIPA can centrally manage sudo rules</p>
<p>Generic rules</p>
<ul>
<li>sudo added support for regexes</li>
</ul>
<p>Polkit action defintions are local XML-based files.
Polkit authorziation rules are written in javascript, have to be local files.</p>
<p>sudo-rs: missing features</p>
<h4 id="questions--thoughts--6">Questions &amp; thoughts 🤔</h4>
<p>Is the goal of sudo-rs to have feature parity with sudo?</p>
<p>I should look into how polkit handles <a href="/notes/fga">fine grained authorziation</a>.</p>
<h2 id="rust-devroom--lightning-lightning-talks">Rust Devroom &amp; Lightning Lightning Talks</h2>
<h3 id="rust-coreutils-in-ubuntu-yes-we-rewrote-bintrue-in-rust--heres-what-really-happened">Rust Coreutils in Ubuntu: Yes, we rewrote /bin/true in Rust &ndash; Here’s what really happened</h3>
<p>Pareto rules: 80 of the work takes 20 of the time</p>
<p>What&rsquo;s next.</p>
<p>Rewrite other GNU utilities.</p>
<h4 id="questions--thoughts--7">Questions &amp; thoughts 🤔</h4>
<p>GPL debate: Is canonical just supporting this so they can get rid of GPL code in their distro?</p>
<h3 id="contributingyaml">CONTRIBUTING.yaml</h3>
<p>CONTRIBUTING.md but machine readable</p>
<ul>
<li>status</li>
<li>intentions</li>
<li>support needs</li>
</ul>
<p>ECMA standarization track.</p>
<p><a href="https://www.tc54.org/contributing-yaml/">https://www.tc54.org/contributing-yaml/</a></p>
<h3 id="misconceptiosn-heard-at-fosdem-about-cra">Misconceptiosn heard at FOSDEM about CRA</h3>
<ul>
<li>No fines for open source projects.</li>
<li>You can take donations.</li>
<li>Your employer won&rsquo;t be liable if you as an employee work on foss</li>
<li>Releasing FOSS does not mean that you need to fill in compliance documents.</li>
<li>an open source steward can be useful, but is not required.</li>
<li>The CRA does not require changes to project processes</li>
<li>&hellip;</li>
</ul>
<h3 id="dumb-guide-to-smart-tvs">Dumb guide to smart TVs</h3>
<p>You pay for:</p>
<ul>
<li>ads</li>
<li>Automatic Content Recognition</li>
<li>Send low quality screenshots to vendor.</li>
<li>the netflix button</li>
</ul>
<p>Nu smart TV allows you to turn off all of the anti-features</p>
<ul>
<li>dont&rsquo;t connect it to the internet</li>
<li>hack your TV!</li>
</ul>
<h3 id="bodybuild">body.build</h3>
<p>Wikipedia bring the best articles, what is the equivalent for fitness?</p>
<ol>
<li>Database of exercises</li>
<li>Applications</li>
</ol>
<ul>
<li>program creator</li>
<li>calorie calculator</li>
<li>&hellip;</li>
</ul>
<p><a href="https://body.build/">https://body.build/</a></p>
<h3 id="postgresql-compatibility-index">PostgreSQL compatibility index</h3>
<p>Not everyone that claims to be PostgreSQL compatible actually is.</p>
<p>Suite to test compatibility.</p>
<h3 id="pacman-cache-server">pacman cache server</h3>
<p>I&rsquo;m not using Arch at the moment so I took no notes 😄.</p>
<h3 id="eu-software-patents-via-upc">EU software patents via UPC</h3>
<p>ffii.org</p>
<h3 id="gui-vs-tui--why-not-both">GUI vs TUI &ndash; Why not both?</h3>
<p>Amazing!</p>
<p>web browser -&gt; wayland -&gt; terminal</p>
<p>Render browser directly to terminal</p>
<p>Not interested in smart but funny.
<a href="https://github.com/dextero/smithay">https://github.com/dextero/smithay</a></p>
<h3 id="git-for-email">Git for email</h3>
<p>Using a git repo to represent emails as files.</p>
<h3 id="rcl-configuration-language">RCL configuration language</h3>
<p>Extends JSON by adding variables functions loops &hellip;</p>
<p>Can also be used to query</p>
<p>🤔 <em>I wonder what the difference is with Jsonnet</em>.</p>
<h3 id="gitify-your-life---14-years-later">Gitify your life - 14 years later</h3>
<p>Etckeeper, bup, ikiwiki, git-annex, metamonger, vcsh, mr, zsh.</p>
<h2 id="main-track">Main track</h2>
<h3 id="open-source-security-in-spite-of-ai">Open Source Security in spite of AI</h3>
<p>Took no notes.</p>
<p><a href="https://daniel.haxx.se/blog/2026/02/03/open-source-security-in-spite-of-ai/">https://daniel.haxx.se/blog/2026/02/03/open-source-security-in-spite-of-ai/</a></p>
<h3 id="closing-fosdem-2026">Closing FOSDEM 2026</h3>
<blockquote>
<p>If we lose our democracies Open Source is irrelevant and goes away!</p>
<p>&ndash; <em>RichiH</em></p>
</blockquote>
<h2 id="talks-i-would-still-like-to-watch-later">Talks I would still like to watch later</h2>
<p>There were a whole lot of talks that I was not able to watch. Luckily talks at
FOSDEM are recorded &amp; avaiable on <a href="https://video.fosdem.org">video.fosdem.org</a>!</p>
<p>Listed <a href="/notes/talks">talks</a>.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Fine-Grained Authorization (FGA)</title>
      <link>https://notes.robinvanhove.me/notes/fga/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/fga/</guid>
      <description>&lt;p&gt;Broken Object Level Authorization is the number one in OWASP&amp;rsquo;s API security
top 10.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;APIs tend to expose endpoints that handle object identifiers, creating a wide
attack surface of Object Level Access Control issues. Object level
authorization checks should be considered in every function that accesses a
data source using an ID from the user.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;what-is-authorization&#34;&gt;What is Authorization?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Decide&lt;/strong&gt; if an action can be taken.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can Alice view document #123?&lt;/li&gt;
&lt;li&gt;Can Alice view document #123 at 16:30 on Tuesday, 11 June, 2024?&lt;/li&gt;
&lt;li&gt;Can Bob edit document #123 in China?&lt;/li&gt;
&lt;li&gt;Can Bob edit document #123 in China, when authenticated with MFA?&lt;/li&gt;
&lt;li&gt;Can a manager create document #456&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can always identify the following:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Broken Object Level Authorization is the number one in OWASP&rsquo;s API security
top 10.</p>
<blockquote>
<p>APIs tend to expose endpoints that handle object identifiers, creating a wide
attack surface of Object Level Access Control issues. Object level
authorization checks should be considered in every function that accesses a
data source using an ID from the user.</p>
</blockquote>
<h2 id="what-is-authorization">What is Authorization?</h2>
<p><strong>Decide</strong> if an action can be taken.</p>
<ul>
<li>Can Alice view document #123?</li>
<li>Can Alice view document #123 at 16:30 on Tuesday, 11 June, 2024?</li>
<li>Can Bob edit document #123 in China?</li>
<li>Can Bob edit document #123 in China, when authenticated with MFA?</li>
<li>Can a manager create document #456</li>
</ul>
<p>We can always identify the following:</p>
<ul>
<li><strong>Subject</strong>, the user or thing trying to take an action
<ul>
<li>Type &amp; identifier
<ul>
<li>E.g. <code>user:Alice</code>, <code>application:123</code></li>
</ul>
</li>
<li>Or properties of the subject
<ul>
<li>E.g. <code>manager</code></li>
</ul>
</li>
</ul>
</li>
<li><strong>Action</strong>, the thing the subject is trying to do
<ul>
<li>E.g. <code>view</code>, <code>edit</code></li>
</ul>
</li>
<li><strong>Resource</strong>, the target of the action
<ul>
<li>Type &amp; identifier</li>
<li>E.g. <code>document:#123</code></li>
</ul>
</li>
<li><strong>Context</strong>, any additional information that can influence the decision.
<ul>
<li>E.g. time, location, authentication method.</li>
</ul>
</li>
</ul>
<p>Additionally we often want to <strong>search</strong> based on the authorization decisions.
A search is essentially a decision with one or more free variables.</p>
<ul>
<li>Which documents can Alice view?</li>
<li>Who can view document 123?</li>
<li>What actions can Alice perform on document 123 on Tuesday, June 11, 2024?</li>
</ul>
<h2 id="access-control-models">Access control models</h2>
<p>Access control models can be separated by their specificity.</p>
<h3 id="coarse-grained-access-control-models">Coarse-grained access control models</h3>
<p><strong>Role-based access control</strong> (RBAC), is the most common access control model.
A subject is assigned to a role and depending on their role the application
decides whether to allow access.</p>
<p>Coarse grained access control models such as RBAC are easy to implement.</p>
<p>It might look like they are easy to manage but in practice group, entitlements
and roles become a mess.</p>
<h3 id="fine-grained-access-context-models">Fine-grained access context models</h3>
<p>Often this is implemented by mapping specific actions on resources to
<strong>entitlements</strong> (arbitrary strings) and combining those in a <strong>role</strong> and
assigning those to a <strong>group</strong> of subjects.</p>
<p><strong>Relationship-based access control</strong> (ReBAC) looks at the relation of
resources and subjects. Essentially it looks at the <strong>graph</strong> of resources and
subjects to decides whether an action is allowed.</p>
<p>
  <img loading="lazy" src="https://cdn.sanity.io/images/4gqsq44z/production/f1c0fdaab8e232d83156f2987513f079c4b648cf-1600x1000.png" alt="ReBAC"  />
<em>From: <a href="https://docs.aserto.com/docs/authorization-basics/authorization-models/rebac">https://docs.aserto.com/docs/authorization-basics/authorization-models/rebac</a></em></p>
<p><strong>Attribute-based access control</strong> (ABAC), compares attributes assigned to a
subject and resource to decide if an action is allowed.</p>
<p><strong>Policy-based access control</strong> (PBAC), the most generic model. A policy can be
any evaluation of any computer program. Often specific domain specific
languages are used to describe the policy.</p>
<h3 id="hybrid-models">Hybrid models</h3>
<p>Coarse-grained and fine-grained can be combined. For example an API gateway or
application proxy can check if a user is allowed to access a service using RBAC
but the service can use a more fine-grained model such as ReBAC to check if
specific actions are allowed on a resource.</p>
<p>This approach can improve performance and provide better (mutli-layered)
security.</p>
<h3 id="googles-zanzibar">Google&rsquo;s Zanzibar</h3>
<blockquote>
<p>Determining whether online users are authorized to access digital objects is
central to preserving privacy. This paper presents the design,
implementation, and deployment of Zanzibar, a global system for storing and
evaluating access control lists. Zanzibar provides a uniform data model and
configuration language for expressing a wide range of access control policies
from hundreds of client services at Google, including Calendar, Cloud, Drive,
Maps, Photos, and YouTube. Its authorization decisions respect causal
ordering of user actions and thus provide external consistency amid changes
to access control lists and object contents. Zanzibar scales to trillions of
access control lists and millions of authorization requests per second to
support services used by billions of people. It has maintained
95th-percentile latency of less than 10 milliseconds and availability of
greater than 99.999% over 3 years of production use.</p>
</blockquote>
<p><a href="https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/">https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/</a></p>
<h2 id="authorization-policies">Authorization Policies</h2>
<p>These describe the rules. From <a href="https://csrc.nist.gov/pubs/sp/800/162/upd2/final">Nist&rsquo;s guide to ABAC</a>:</p>
<blockquote>
<p><strong>Natural Language Policy</strong> (NLP): Statements governing management and access
of enterprise objects. NLPs are human expressions that can be translated to
machine-enforceable access control policies.</p>
</blockquote>
<blockquote>
<p><strong>Digital Policy</strong> (DP): Access control rules that compile directly into
machine executable codes or signals. Subject/object attributes, operations,
and environment conditions are the fundamental elements of DP, the building
blocks of DP rules, which are enforced by an access control mechanism.</p>
</blockquote>
<blockquote>
<p><strong>Metapolicy</strong> (MP): A policy about policies, or policy for managing
policies, such as assignment of priorities and resolution of conflicts
between DPs or other MPs.</p>
</blockquote>
<p>Digital policies are the real software implementation of the policy. These are
often described using A DCL XACML, ALFA, Rego, Oso Polar.</p>
<p>A policy evaluation <strong>engine</strong> takes the authorization policy, and the
authorization request and outputs a decision.</p>
<h3 id="digital-policy-example-with-rego">Digital Policy example with Rego</h3>
<p>Rego is currently the most popular and open language for to define policies, it
was developed for the OPA policy engine and is based on the datalog programming language.</p>
<p>Rego is a <strong>declerative</strong> programming language, made for writing authorization policies.</p>
<p>The following is an example from the <a href="https://play.openpolicyagent.org/">Rego playground</a>.</p>
<p><strong>Policy:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-Rego" data-lang="Rego"><span style="display:flex;"><span><span style="color:#66d9ef">package</span> <span style="color:#a6e22e">app</span><span style="color:#f92672">.</span><span style="color:#a6e22e">abac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">default</span> <span style="color:#a6e22e">allow</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">user_is_owner</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_employee</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">action_is_read</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_employee</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_senior</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">action_is_update</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_customer</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">action_is_read</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">not</span> <span style="color:#a6e22e">pet_is_adopted</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_owner <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">title</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;owner&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_employee <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">title</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;employee&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_customer <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">title</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;customer&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_senior <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">tenure</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>action_is_read <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">action</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;read&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>action_is_update <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">action</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;update&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pet_is_adopted <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">pet_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">resource</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">adopted</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">true</span>
</span></span></code></pre></div><p><strong>Data:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user_attributes&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;alice&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tenure&#34;</span>: <span style="color:#ae81ff">20</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;owner&#34;</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;pet_attributes&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;dog123&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;adopted&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;age&#34;</span>: <span style="color:#ae81ff">2</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;breed&#34;</span>: <span style="color:#e6db74">&#34;terrier&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;toto&#34;</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Input:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;action&#34;</span>: <span style="color:#e6db74">&#34;read&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;resource&#34;</span>: <span style="color:#e6db74">&#34;dog123&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;action_is_read&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;allow&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;pet_is_adopted&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user_is_owner&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user_is_senior&#34;</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="externalized-authorization-architecture">Externalized Authorization Architecture</h2>
<p>Often the authorization is implemented in the application itself, either
hard-coded or trough configurations. But this approach has shortcomings in
large, distributed and dynamic systems.</p>
<ul>
<li>Policy (interpretation) consistency</li>
<li>Reuse of implementations</li>
<li>Policy administration (version control, deployments)</li>
<li>More difficult to improve performance</li>
</ul>
<p>For these reasons it is often decided to externalize authorization out of the application.</p>
<p>The simplest approach to externalize  authorization is to <strong>centralize</strong> it in
one system. But there are other patterns possible, more on that later.</p>
<p>Defined in
<a href="https://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html">XACML</a>
and  <a href="https://csrc.nist.gov/pubs/sp/800/162/upd2/final">Nist&rsquo;s guide to ABAC</a></p>
<p>
  <img loading="lazy" src="https://upload.wikimedia.org/wikipedia/commons/f/f2/XACML_Architecture_%26_Flow.png" alt="XACML
Architecture"  />
<em>By Axiomatics - Axiomatics, CC BY 3.0,
<a href="https://commons.wikimedia.org/w/index.php?curid=48397652">https://commons.wikimedia.org/w/index.php?curid=48397652</a></em></p>
<p>
  <img loading="lazy" src="https://www.researchgate.net/publication/336538309/figure/fig2/AS:814067111436288@1571100132236/ACML-Standard-Oasis-2010-As-shown-in-the-Fig-3-above-the-major-components-of-XACML.ppm" alt="XACML Dataflow
Diagram"  />
<em>XACML Dataflow Diagram, image from OASIS spec.</em></p>
<h3 id="policy-decision-point-components">Policy Decision point components</h3>
<p>The PDP is shown as one component in the XACML architecture but we can
distinguish multiple subcomponents.</p>
<p><strong>Policy Engine</strong> is the component responsible for actually evaluating the
policy and making a decision.</p>
<p><strong>PDP Interface</strong> or <strong>API</strong> implements how the PEP can send queries to th PDP.
Often based upon HTTP and JSON but gRCP. Every PDP implementation uses a
different kind of (often proprietary API). But there is a process ongoing by
the OpenID foundation to standerize an interface called <strong>AuthZEN</strong>.</p>
<p>The <strong>data plane</strong> is responsible for gathering data form the relevant PIP&rsquo;s.
E.g. user &amp; resource attributes. The data plane can also concern itself with
<strong>caching</strong> and structuring the data in a performant <strong>data structure</strong> such as
a graph for performant policy evaluation.</p>
<p>The data plane can exist completely separate from the PDP (any databse or API
can be used). But many implementations choose to tightly couple the PDP and PIP
for optimal performance.</p>
<p>A <strong>policy control plane</strong> is required to distribute updates to policies the
PDP&rsquo;s as soon as they are changed. The control plane is the glue between the
PAP and PDP. The control plane can also provide information about the
configuration of the data plane, such as the location of the PIP&rsquo;s.</p>
<h3 id="fancy-archtiectural-patterns">Fancy Archtiectural patterns</h3>
<p>
  <img loading="lazy" src="https://i.ibb.co/F45Q7bC/main-numbered.png" alt="OPAL Architecture"  />
<em>OPAL Architecture, from <a href="https://docs.opal.ac/overview/architecture/">https://docs.opal.ac/overview/architecture/</a></em></p>
<ul>
<li>Fully centralized service</li>
<li>Per-tenant</li>
<li>Per application
<ul>
<li>As a library</li>
<li>Sidecar container</li>
</ul>
</li>
</ul>
<h2 id="policy-administration-pap">Policy administration (PAP)</h2>
<p>Many solutions provide powerful interfaces to manage policies.</p>
<p><strong>Policy creation</strong> interface. The digital policy can be written as computer
program using any text editor or IDE. But many implementations provide
interfaces to make it easy to use for less technical people.</p>
<p><strong>Version control</strong> is essential for policy management. Often software VCS such
as git ore often used because most operations are already using it. But
sometimes authorization services implement their own version control, tightly
coupled with the ui of the PAP.</p>
<p><strong>Policy distribution</strong> trough the <strong>control plane</strong>, just like any program the
authorization policies require some form of <strong>continous deployent</strong>, depending
on the chosen architecture this can become very complex, requiring deployment
to multiple PDP&rsquo;s without having downtime.</p>
<p><strong>Testing</strong> should also be considered, the digital policy is a computer program
like any other and there should exist &lsquo;unit&rsquo; test to ensure that the policies
(and any for changes) behave as expected. Issues in a policy can have huge
consequences for the security of the system.</p>
<h2 id="authzen">AuthZEN</h2>
<p>The OpenID foudnation has identified the need for a standardized interface for
authorization, similar to their OpenID connect standard for authentication.</p>
<p><a href="https://openid.github.io/authzen/">https://openid.github.io/authzen/</a></p>
<p>AuthZEN is essentially an API specification standardizing the contract between
PDP and PEP. It contains two API&rsquo;s.</p>
<ul>
<li>Access Evaluation(s) API</li>
<li>Search API</li>
</ul>
<h3 id="access-evaluation-api">Access Evaluation API</h3>
<p><em>Modified example from the AuthZEN draft.</em></p>
<p>The access evaluation API returns the decision as a boolean, but can also provide some context.</p>
<p>An alternative endpoint is also defined that can evaluate multiple decisions in one request.</p>
<p><strong>Request:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#a6e22e">POST</span> /access/v1/evaluation <span style="color:#66d9ef">HTTP</span><span style="color:#f92672">/</span><span style="color:#ae81ff">1.1</span>
</span></span><span style="display:flex;"><span>Host<span style="color:#f92672">:</span> <span style="color:#ae81ff">pdp.example.com</span>
</span></span><span style="display:flex;"><span>Content-Type<span style="color:#f92672">:</span> <span style="color:#ae81ff">application/json</span>
</span></span><span style="display:flex;"><span>Authorization<span style="color:#f92672">:</span> <span style="color:#ae81ff">Bearer &lt;myoauthtoken&gt;</span>
</span></span><span style="display:flex;"><span>X-Request-ID<span style="color:#f92672">:</span> <span style="color:#ae81ff">bfe9eb29-ab87-4ca3-be83-a1d5d8305716</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;subject&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;resource&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;document&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;1&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;action&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;edit&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;context&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;time&#34;</span>: <span style="color:#e6db74">&#34;1985-10-26T01:22-07:00&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Response:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">HTTP/1.1 OK
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">Content-Type: application/json
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">X-Request-ID: bfe9eb29-ab87-4ca3-be83-a1d5d8305716
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;decision&#34;</span>: <span style="color:#66d9ef">false</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;context&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;reason&#34;</span>: <span style="color:#e6db74">&#34;Subject is a viewer of the resource&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="search-api">Search API</h3>
<p><em>Example form the draft.</em></p>
<p>The search API can search for subjects, actions and resources.</p>
<p>It also specifies  <strong>pagination</strong> which is which is essential for scalability.</p>
<p><strong>Request:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#a6e22e">POST</span> /access/v1/search/resource <span style="color:#66d9ef">HTTP</span><span style="color:#f92672">/</span><span style="color:#ae81ff">1.1</span>
</span></span><span style="display:flex;"><span>Host<span style="color:#f92672">:</span> <span style="color:#ae81ff">pdp.example.com</span>
</span></span><span style="display:flex;"><span>Content-Type<span style="color:#f92672">:</span> <span style="color:#ae81ff">application/json</span>
</span></span><span style="display:flex;"><span>Authorization<span style="color:#f92672">:</span> <span style="color:#ae81ff">Bearer &lt;myoauthtoken&gt;</span>
</span></span><span style="display:flex;"><span>X-Request-ID<span style="color:#f92672">:</span> <span style="color:#ae81ff">bfe9eb29-ab87-4ca3-be83-a1d5d8305716</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;subject&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;action&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;can_read&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;resource&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;account&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Response:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">HTTP/1.1 OK
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">Content-Type: application/json
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">X-Request-ID: bfe9eb29-ab87-4ca3-be83-a1d5d8305716
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;page&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;next_token&#34;</span>: <span style="color:#e6db74">&#34;a3M9NDU2O3N6PTI=&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;results&#34;</span>: [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;account&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;123&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;account&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;456&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="oauth-rich-authorization-requests">OAuth Rich Authorization Requests</h3>
<p>There also exists an extension to famout OAuth authorization framework to
implement FGA.</p>
<p>Ideal for when <strong>user interaction</strong> (permission) is required before allowing a
service to take an action. Or for <strong>cross-domain</strong> use cases.</p>
<p>From RFC 9396: OAuth 2.0 Rich Authorization Requests:</p>
<blockquote>
<p>This specification introduces a new parameter authorization_details that
allows clients to specify their fine-grained authorization requirements using
the expressiveness of JSON data structures.</p>
</blockquote>
<blockquote>
<p>For example, an authorization request for a credit transfer (designated as
&ldquo;payment initiation&rdquo; in several open banking initiatives) can be represented
using a JSON object like this:</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;payment_initiation&#34;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;locations&#34;</span>: [
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#34;https://example.com/payments&#34;</span>
</span></span><span style="display:flex;"><span>   ],
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;instructedAmount&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;currency&#34;</span>: <span style="color:#e6db74">&#34;EUR&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;amount&#34;</span>: <span style="color:#e6db74">&#34;123.50&#34;</span>
</span></span><span style="display:flex;"><span>   },
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;creditorName&#34;</span>: <span style="color:#e6db74">&#34;Merchant A&#34;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;creditorAccount&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;bic&#34;</span>:<span style="color:#e6db74">&#34;ABCIDEFFXXX&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;iban&#34;</span>: <span style="color:#e6db74">&#34;DE02100100109307118603&#34;</span>
</span></span><span style="display:flex;"><span>   },
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;remittanceInformationUnstructured&#34;</span>: <span style="color:#e6db74">&#34;Ref Number Merchant&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><em>From RFC 9396: Example of an Authorization Request for a Credit Transfer</em></p>
<h2 id="the-new-enemy-problem">The new enemy problem</h2>
<h2 id="audit-logs">Audit logs</h2>
<p>An advantage is centralizing the authorization is that it also become easier to
centralize the <strong>decision logs</strong>. These are very useful for auditing.</p>
<h2 id="projects-and-products">Projects and products</h2>
<h3 id="open-source-with-commercial-offering">Open source with commercial offering</h3>
<p>All most all (production ready) open source implementations of FGA are backed
by a commercial company providing a product based upon the open-source project.</p>
<p>Open source / Commercial product.</p>
<ul>
<li>OPA / Styra enterprise OPA &amp; DAS</li>
<li>OPAL / Permit.io</li>
<li>Aserto / Topaz</li>
<li>spiceDB / AuhtZed</li>
<li>OpenFGA / Auth0 (Okta) FGA</li>
<li>Casbin / Casdoor</li>
</ul>
<h3 id="proprietary">Proprietary</h3>
<p>Several companies also sell fully closed source authorization services.</p>
<ul>
<li>Oso Security</li>
<li>Ping Authorize</li>
<li>AWS Cedar</li>
<li>Axiomatics</li>
<li>Permify</li>
<li>Cerbos</li>
</ul>
<h2 id="sources--further-reading">Sources &amp; further reading</h2>
<ul>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/">https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/</a></li>
<li><a href="https://idpro.org/the-state-of-the-union-of-authorization/">https://idpro.org/the-state-of-the-union-of-authorization/</a></li>
<li><a href="https://www.permit.io/blog/what-is-fine-grained-authorization-fga">https://www.permit.io/blog/what-is-fine-grained-authorization-fga</a></li>
<li><a href="https://openid.net/wg/authzen/">https://openid.net/wg/authzen/</a></li>
<li><a href="https://openid.github.io/authzen/">https://openid.github.io/authzen/</a></li>
<li><a href="https://www.feldera.com/blog/fine-grained-authorization">https://www.feldera.com/blog/fine-grained-authorization</a></li>
<li><a href="https://docs.aserto.com/docs/authorization-basics">https://docs.aserto.com/docs/authorization-basics</a></li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc9396">https://datatracker.ietf.org/doc/html/rfc9396</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Fine-Grained Authorization (FGA)</title>
      <link>https://notes.robinvanhove.me/notes/test2x/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/test2x/</guid>
      <description>&lt;p&gt;Broken Object Level Authorization is the number one in OWASP&amp;rsquo;s API security
top 10.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;APIs tend to expose endpoints that handle object identifiers, creating a wide
attack surface of Object Level Access Control issues. Object level
authorization checks should be considered in every function that accesses a
data source using an ID from the user.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;what-is-authorization&#34;&gt;What is Authorization?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Decide&lt;/strong&gt; if an action can be taken.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can Alice view document #123?&lt;/li&gt;
&lt;li&gt;Can Alice view document #123 at 16:30 on Tuesday, 11 June, 2024?&lt;/li&gt;
&lt;li&gt;Can Bob edit document #123 in China?&lt;/li&gt;
&lt;li&gt;Can Bob edit document #123 in China, when authenticated with MFA?&lt;/li&gt;
&lt;li&gt;Can a manager create document #456&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We can always identify the following:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Broken Object Level Authorization is the number one in OWASP&rsquo;s API security
top 10.</p>
<blockquote>
<p>APIs tend to expose endpoints that handle object identifiers, creating a wide
attack surface of Object Level Access Control issues. Object level
authorization checks should be considered in every function that accesses a
data source using an ID from the user.</p>
</blockquote>
<h2 id="what-is-authorization">What is Authorization?</h2>
<p><strong>Decide</strong> if an action can be taken.</p>
<ul>
<li>Can Alice view document #123?</li>
<li>Can Alice view document #123 at 16:30 on Tuesday, 11 June, 2024?</li>
<li>Can Bob edit document #123 in China?</li>
<li>Can Bob edit document #123 in China, when authenticated with MFA?</li>
<li>Can a manager create document #456</li>
</ul>
<p>We can always identify the following:</p>
<ul>
<li><strong>Subject</strong>, the user or thing trying to take an action
<ul>
<li>Type &amp; identifier
<ul>
<li>E.g. <code>user:Alice</code>, <code>application:123</code></li>
</ul>
</li>
<li>Or properties of the subject
<ul>
<li>E.g. <code>manager</code></li>
</ul>
</li>
</ul>
</li>
<li><strong>Action</strong>, the thing the subject is trying to do
<ul>
<li>E.g. <code>view</code>, <code>edit</code></li>
</ul>
</li>
<li><strong>Resource</strong>, the target of the action
<ul>
<li>Type &amp; identifier</li>
<li>E.g. <code>document:#123</code></li>
</ul>
</li>
<li><strong>Context</strong>, any additional information that can influence the decision.
<ul>
<li>E.g. time, location, authentication method.</li>
</ul>
</li>
</ul>
<p>Additionally we often want to <strong>search</strong> based on the authorization decisions.
A search is essentially a decision with one or more free variables.</p>
<ul>
<li>Which documents can Alice view?</li>
<li>Who can view document 123?</li>
<li>What actions can Alice perform on document 123 on Tuesday, June 11, 2024?</li>
</ul>
<h2 id="access-control-models">Access control models</h2>
<p>Access control models can be separated by their specificity.</p>
<h3 id="coarse-grained-access-control-models">Coarse-grained access control models</h3>
<p><strong>Role-based access control</strong> (RBAC), is the most common access control model.
A subject is assigned to a role and depending on their role the application
decides whether to allow access.</p>
<p>Coarse grained access control models such as RBAC are easy to implement.</p>
<p>It might look like they are easy to manage but in practice group, entitlements
and roles become a mess.</p>
<h3 id="fine-grained-access-context-models">Fine-grained access context models</h3>
<p>Often this is implemented by mapping specific actions on resources to
<strong>entitlements</strong> (arbitrary strings) and combining those in a <strong>role</strong> and
assigning those to a <strong>group</strong> of subjects.</p>
<p><strong>Relationship-based access control</strong> (ReBAC) looks at the relation of
resources and subjects. Essentially it looks at the <strong>graph</strong> of resources and
subjects to decides whether an action is allowed.</p>
<p>
  <img loading="lazy" src="https://cdn.sanity.io/images/4gqsq44z/production/f1c0fdaab8e232d83156f2987513f079c4b648cf-1600x1000.png" alt="ReBAC"  />
<em>From: <a href="https://docs.aserto.com/docs/authorization-basics/authorization-models/rebac">https://docs.aserto.com/docs/authorization-basics/authorization-models/rebac</a></em></p>
<p><strong>Attribute-based access control</strong> (ABAC), compares attributes assigned to a
subject and resource to decide if an action is allowed.</p>
<p><strong>Policy-based access control</strong> (PBAC), the most generic model. A policy can be
any evaluation of any computer program. Often specific domain specific
languages are used to describe the policy.</p>
<h3 id="hybrid-models">Hybrid models</h3>
<p>Coarse-grained and fine-grained can be combined. For example an API gateway or
application proxy can check if a user is allowed to access a service using RBAC
but the service can use a more fine-grained model such as ReBAC to check if
specific actions are allowed on a resource.</p>
<p>This approach can improve performance and provide better (mutli-layered)
security.</p>
<h3 id="googles-zanzibar">Google&rsquo;s Zanzibar</h3>
<blockquote>
<p>Determining whether online users are authorized to access digital objects is
central to preserving privacy. This paper presents the design,
implementation, and deployment of Zanzibar, a global system for storing and
evaluating access control lists. Zanzibar provides a uniform data model and
configuration language for expressing a wide range of access control policies
from hundreds of client services at Google, including Calendar, Cloud, Drive,
Maps, Photos, and YouTube. Its authorization decisions respect causal
ordering of user actions and thus provide external consistency amid changes
to access control lists and object contents. Zanzibar scales to trillions of
access control lists and millions of authorization requests per second to
support services used by billions of people. It has maintained
95th-percentile latency of less than 10 milliseconds and availability of
greater than 99.999% over 3 years of production use.</p>
</blockquote>
<p><a href="https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/">https://research.google/pubs/zanzibar-googles-consistent-global-authorization-system/</a></p>
<h2 id="authorization-policies">Authorization Policies</h2>
<p>These describe the rules. From <a href="https://csrc.nist.gov/pubs/sp/800/162/upd2/final">Nist&rsquo;s guide to ABAC</a>:</p>
<blockquote>
<p><strong>Natural Language Policy</strong> (NLP): Statements governing management and access
of enterprise objects. NLPs are human expressions that can be translated to
machine-enforceable access control policies.</p>
</blockquote>
<blockquote>
<p><strong>Digital Policy</strong> (DP): Access control rules that compile directly into
machine executable codes or signals. Subject/object attributes, operations,
and environment conditions are the fundamental elements of DP, the building
blocks of DP rules, which are enforced by an access control mechanism.</p>
</blockquote>
<blockquote>
<p><strong>Metapolicy</strong> (MP): A policy about policies, or policy for managing
policies, such as assignment of priorities and resolution of conflicts
between DPs or other MPs.</p>
</blockquote>
<p>Digital policies are the real software implementation of the policy. These are
often described using A DCL XACML, ALFA, Rego, Oso Polar.</p>
<p>A policy evaluation <strong>engine</strong> takes the authorization policy, and the
authorization request and outputs a decision.</p>
<h3 id="digital-policy-example-with-rego">Digital Policy example with Rego</h3>
<p>Rego is currently the most popular and open language for to define policies, it
was developed for the OPA policy engine and is based on the datalog programming language.</p>
<p>Rego is a <strong>declerative</strong> programming language, made for writing authorization policies.</p>
<p>The following is an example from the <a href="https://play.openpolicyagent.org/">Rego playground</a>.</p>
<p><strong>Policy:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-Rego" data-lang="Rego"><span style="display:flex;"><span><span style="color:#66d9ef">package</span> <span style="color:#a6e22e">app</span><span style="color:#f92672">.</span><span style="color:#a6e22e">abac</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">default</span> <span style="color:#a6e22e">allow</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">user_is_owner</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_employee</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">action_is_read</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_employee</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_senior</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">action_is_update</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>allow <span style="color:#66d9ef">if</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">user_is_customer</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">action_is_read</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">not</span> <span style="color:#a6e22e">pet_is_adopted</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_owner <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">title</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;owner&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_employee <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">title</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;employee&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_customer <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">title</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;customer&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>user_is_senior <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">user</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">tenure</span> <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>action_is_read <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">action</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;read&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>action_is_update <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">action</span> <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;update&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>pet_is_adopted <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">.</span><span style="color:#a6e22e">pet_attributes</span>[<span style="color:#a6e22e">input</span><span style="color:#f92672">.</span><span style="color:#a6e22e">resource</span>]<span style="color:#f92672">.</span><span style="color:#a6e22e">adopted</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">true</span>
</span></span></code></pre></div><p><strong>Data:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user_attributes&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;alice&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;tenure&#34;</span>: <span style="color:#ae81ff">20</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;owner&#34;</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;pet_attributes&#34;</span>: {
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&#34;dog123&#34;</span>: {
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;adopted&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;age&#34;</span>: <span style="color:#ae81ff">2</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;breed&#34;</span>: <span style="color:#e6db74">&#34;terrier&#34;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;toto&#34;</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Input:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user&#34;</span>: <span style="color:#e6db74">&#34;alice&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;action&#34;</span>: <span style="color:#e6db74">&#34;read&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;resource&#34;</span>: <span style="color:#e6db74">&#34;dog123&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Output:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;action_is_read&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;allow&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;pet_is_adopted&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user_is_owner&#34;</span>: <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;user_is_senior&#34;</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="externalized-authorization-architecture">Externalized Authorization Architecture</h2>
<p>Often the authorization is implemented in the application itself, either
hard-coded or trough configurations. But this approach has shortcomings in
large, distributed and dynamic systems.</p>
<ul>
<li>Policy (interpretation) consistency</li>
<li>Reuse of implementations</li>
<li>Policy administration (version control, deployments)</li>
<li>More difficult to improve performance</li>
</ul>
<p>For these reasons it is often decided to externalize authorization out of the application.</p>
<p>The simplest approach to externalize  authorization is to <strong>centralize</strong> it in
one system. But there are other patterns possible, more on that later.</p>
<p>Defined in
<a href="https://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html">XACML</a>
and  <a href="https://csrc.nist.gov/pubs/sp/800/162/upd2/final">Nist&rsquo;s guide to ABAC</a></p>
<p>
  <img loading="lazy" src="https://upload.wikimedia.org/wikipedia/commons/f/f2/XACML_Architecture_%26_Flow.png" alt="XACML
Architecture"  />
<em>By Axiomatics - Axiomatics, CC BY 3.0,
<a href="https://commons.wikimedia.org/w/index.php?curid=48397652">https://commons.wikimedia.org/w/index.php?curid=48397652</a></em></p>
<p>
  <img loading="lazy" src="https://www.researchgate.net/publication/336538309/figure/fig2/AS:814067111436288@1571100132236/ACML-Standard-Oasis-2010-As-shown-in-the-Fig-3-above-the-major-components-of-XACML.ppm" alt="XACML Dataflow
Diagram"  />
<em>XACML Dataflow Diagram, image from OASIS spec.</em></p>
<h3 id="policy-decision-point-components">Policy Decision point components</h3>
<p>The PDP is shown as one component in the XACML architecture but we can
distinguish multiple subcomponents.</p>
<p><strong>Policy Engine</strong> is the component responsible for actually evaluating the
policy and making a decision.</p>
<p><strong>PDP Interface</strong> or <strong>API</strong> implements how the PEP can send queries to th PDP.
Often based upon HTTP and JSON but gRCP. Every PDP implementation uses a
different kind of (often proprietary API). But there is a process ongoing by
the OpenID foundation to standerize an interface called <strong>AuthZEN</strong>.</p>
<p>The <strong>data plane</strong> is responsible for gathering data form the relevant PIP&rsquo;s.
E.g. user &amp; resource attributes. The data plane can also concern itself with
<strong>caching</strong> and structuring the data in a performant <strong>data structure</strong> such as
a graph for performant policy evaluation.</p>
<p>The data plane can exist completely separate from the PDP (any databse or API
can be used). But many implementations choose to tightly couple the PDP and PIP
for optimal performance.</p>
<p>A <strong>policy control plane</strong> is required to distribute updates to policies the
PDP&rsquo;s as soon as they are changed. The control plane is the glue between the
PAP and PDP. The control plane can also provide information about the
configuration of the data plane, such as the location of the PIP&rsquo;s.</p>
<h3 id="fancy-archtiectural-patterns">Fancy Archtiectural patterns</h3>
<p>
  <img loading="lazy" src="https://i.ibb.co/F45Q7bC/main-numbered.png" alt="OPAL Architecture"  />
<em>OPAL Architecture, from <a href="https://docs.opal.ac/overview/architecture/">https://docs.opal.ac/overview/architecture/</a></em></p>
<ul>
<li>Fully centralized service</li>
<li>Per-tenant</li>
<li>Per application
<ul>
<li>As a library</li>
<li>Sidecar container</li>
</ul>
</li>
</ul>
<h2 id="policy-administration-pap">Policy administration (PAP)</h2>
<p>Many solutions provide powerful interfaces to manage policies.</p>
<p><strong>Policy creation</strong> interface. The digital policy can be written as computer
program using any text editor or IDE. But many implementations provide
interfaces to make it easy to use for less technical people.</p>
<p><strong>Version control</strong> is essential for policy management. Often software VCS such
as git ore often used because most operations are already using it. But
sometimes authorization services implement their own version control, tightly
coupled with the ui of the PAP.</p>
<p><strong>Policy distribution</strong> trough the <strong>control plane</strong>, just like any program the
authorization policies require some form of <strong>continous deployent</strong>, depending
on the chosen architecture this can become very complex, requiring deployment
to multiple PDP&rsquo;s without having downtime.</p>
<p><strong>Testing</strong> should also be considered, the digital policy is a computer program
like any other and there should exist &lsquo;unit&rsquo; test to ensure that the policies
(and any for changes) behave as expected. Issues in a policy can have huge
consequences for the security of the system.</p>
<h2 id="authzen">AuthZEN</h2>
<p>The OpenID foudnation has identified the need for a standardized interface for
authorization, similar to their OpenID connect standard for authentication.</p>
<p><a href="https://openid.github.io/authzen/">https://openid.github.io/authzen/</a></p>
<p>AuthZEN is essentially an API specification standardizing the contract between
PDP and PEP. It contains two API&rsquo;s.</p>
<ul>
<li>Access Evaluation(s) API</li>
<li>Search API</li>
</ul>
<h3 id="access-evaluation-api">Access Evaluation API</h3>
<p><em>Modified example from the AuthZEN draft.</em></p>
<p>The access evaluation API returns the decision as a boolean, but can also provide some context.</p>
<p>An alternative endpoint is also defined that can evaluate multiple decisions in one request.</p>
<p><strong>Request:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#a6e22e">POST</span> /access/v1/evaluation <span style="color:#66d9ef">HTTP</span><span style="color:#f92672">/</span><span style="color:#ae81ff">1.1</span>
</span></span><span style="display:flex;"><span>Host<span style="color:#f92672">:</span> <span style="color:#ae81ff">pdp.example.com</span>
</span></span><span style="display:flex;"><span>Content-Type<span style="color:#f92672">:</span> <span style="color:#ae81ff">application/json</span>
</span></span><span style="display:flex;"><span>Authorization<span style="color:#f92672">:</span> <span style="color:#ae81ff">Bearer &lt;myoauthtoken&gt;</span>
</span></span><span style="display:flex;"><span>X-Request-ID<span style="color:#f92672">:</span> <span style="color:#ae81ff">bfe9eb29-ab87-4ca3-be83-a1d5d8305716</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;subject&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;resource&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;document&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;1&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;action&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;edit&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;context&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;time&#34;</span>: <span style="color:#e6db74">&#34;1985-10-26T01:22-07:00&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Response:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">HTTP/1.1 OK
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">Content-Type: application/json
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">X-Request-ID: bfe9eb29-ab87-4ca3-be83-a1d5d8305716
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;decision&#34;</span>: <span style="color:#66d9ef">false</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;context&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;reason&#34;</span>: <span style="color:#e6db74">&#34;Subject is a viewer of the resource&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="search-api">Search API</h3>
<p><em>Example form the draft.</em></p>
<p>The search API can search for subjects, actions and resources.</p>
<p>It also specifies  <strong>pagination</strong> which is which is essential for scalability.</p>
<p><strong>Request:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#a6e22e">POST</span> /access/v1/search/resource <span style="color:#66d9ef">HTTP</span><span style="color:#f92672">/</span><span style="color:#ae81ff">1.1</span>
</span></span><span style="display:flex;"><span>Host<span style="color:#f92672">:</span> <span style="color:#ae81ff">pdp.example.com</span>
</span></span><span style="display:flex;"><span>Content-Type<span style="color:#f92672">:</span> <span style="color:#ae81ff">application/json</span>
</span></span><span style="display:flex;"><span>Authorization<span style="color:#f92672">:</span> <span style="color:#ae81ff">Bearer &lt;myoauthtoken&gt;</span>
</span></span><span style="display:flex;"><span>X-Request-ID<span style="color:#f92672">:</span> <span style="color:#ae81ff">bfe9eb29-ab87-4ca3-be83-a1d5d8305716</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;subject&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;alice@example.com&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;action&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;can_read&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;resource&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;account&#34;</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>Response:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-http" data-lang="http"><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">HTTP/1.1 OK
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">Content-Type: application/json
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">X-Request-ID: bfe9eb29-ab87-4ca3-be83-a1d5d8305716
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;page&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;next_token&#34;</span>: <span style="color:#e6db74">&#34;a3M9NDU2O3N6PTI=&#34;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;results&#34;</span>: [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;account&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;123&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;account&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;456&#34;</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="oauth-rich-authorization-requests">OAuth Rich Authorization Requests</h3>
<p>There also exists an extension to famout OAuth authorization framework to
implement FGA.</p>
<p>Ideal for when <strong>user interaction</strong> (permission) is required before allowing a
service to take an action. Or for <strong>cross-domain</strong> use cases.</p>
<p>From RFC 9396: OAuth 2.0 Rich Authorization Requests:</p>
<blockquote>
<p>This specification introduces a new parameter authorization_details that
allows clients to specify their fine-grained authorization requirements using
the expressiveness of JSON data structures.</p>
</blockquote>
<blockquote>
<p>For example, an authorization request for a credit transfer (designated as
&ldquo;payment initiation&rdquo; in several open banking initiatives) can be represented
using a JSON object like this:</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;type&#34;</span>: <span style="color:#e6db74">&#34;payment_initiation&#34;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;locations&#34;</span>: [
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#34;https://example.com/payments&#34;</span>
</span></span><span style="display:flex;"><span>   ],
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;instructedAmount&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;currency&#34;</span>: <span style="color:#e6db74">&#34;EUR&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;amount&#34;</span>: <span style="color:#e6db74">&#34;123.50&#34;</span>
</span></span><span style="display:flex;"><span>   },
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;creditorName&#34;</span>: <span style="color:#e6db74">&#34;Merchant A&#34;</span>,
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;creditorAccount&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;bic&#34;</span>:<span style="color:#e6db74">&#34;ABCIDEFFXXX&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;iban&#34;</span>: <span style="color:#e6db74">&#34;DE02100100109307118603&#34;</span>
</span></span><span style="display:flex;"><span>   },
</span></span><span style="display:flex;"><span>   <span style="color:#f92672">&#34;remittanceInformationUnstructured&#34;</span>: <span style="color:#e6db74">&#34;Ref Number Merchant&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><em>From RFC 9396: Example of an Authorization Request for a Credit Transfer</em></p>
<h2 id="the-new-enemy-problem">The new enemy problem</h2>
<h2 id="audit-logs">Audit logs</h2>
<p>An advantage is centralizing the authorization is that it also become easier to
centralize the <strong>decision logs</strong>. These are very useful for auditing.</p>
<h2 id="projects-and-products">Projects and products</h2>
<h3 id="open-source-with-commercial-offering">Open source with commercial offering</h3>
<p>All most all (production ready) open source implementations of FGA are backed
by a commercial company providing a product based upon the open-source project.</p>
<p>Open source / Commercial product.</p>
<ul>
<li>OPA / Styra enterprise OPA &amp; DAS</li>
<li>OPAL / Permit.io</li>
<li>Aserto / Topaz</li>
<li>spiceDB / AuhtZed</li>
<li>OpenFGA / Auth0 (Okta) FGA</li>
<li>Casbin / Casdoor</li>
</ul>
<h3 id="proprietary">Proprietary</h3>
<p>Several companies also sell fully closed source authorization services.</p>
<ul>
<li>Oso Security</li>
<li>Ping Authorize</li>
<li>AWS Cedar</li>
<li>Axiomatics</li>
<li>Permify</li>
<li>Cerbos</li>
</ul>
<h2 id="sources--further-reading">Sources &amp; further reading</h2>
<ul>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/">https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/</a></li>
<li><a href="https://idpro.org/the-state-of-the-union-of-authorization/">https://idpro.org/the-state-of-the-union-of-authorization/</a></li>
<li><a href="https://www.permit.io/blog/what-is-fine-grained-authorization-fga">https://www.permit.io/blog/what-is-fine-grained-authorization-fga</a></li>
<li><a href="https://openid.net/wg/authzen/">https://openid.net/wg/authzen/</a></li>
<li><a href="https://openid.github.io/authzen/">https://openid.github.io/authzen/</a></li>
<li><a href="https://www.feldera.com/blog/fine-grained-authorization">https://www.feldera.com/blog/fine-grained-authorization</a></li>
<li><a href="https://docs.aserto.com/docs/authorization-basics">https://docs.aserto.com/docs/authorization-basics</a></li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc9396">https://datatracker.ietf.org/doc/html/rfc9396</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Multi Factor Authentication</title>
      <link>https://notes.robinvanhove.me/notes/mfa/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/mfa/</guid>
      <description>&lt;h1 id=&#34;what-is-mfa&#34;&gt;What is MFA&lt;/h1&gt;
&lt;p&gt;Multi-factor authentication (MFA) is a security process that requires users to
verify their identity using two or more distinct factors. Each factor can be
from one of the following categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Something you know (e.g., a password)&lt;/li&gt;
&lt;li&gt;Something you have (e.g., a security token or mobile device)&lt;/li&gt;
&lt;li&gt;Something you are (e.g., a biometric such as fingerprint or face recognition)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For an authentication method to be secure, it should validate at least two
factors.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h1 id="what-is-mfa">What is MFA</h1>
<p>Multi-factor authentication (MFA) is a security process that requires users to
verify their identity using two or more distinct factors. Each factor can be
from one of the following categories:</p>
<ul>
<li>Something you know (e.g., a password)</li>
<li>Something you have (e.g., a security token or mobile device)</li>
<li>Something you are (e.g., a biometric such as fingerprint or face recognition)</li>
</ul>
<p>For an authentication method to be secure, it should validate at least two
factors.</p>
<h1 id="business-value">Business Value</h1>
<p>Multi-factor authentication (MFA) delivers critical business value by
significantly strengthening security and reducing the risk of data breaches,
phishing, and credential theft, even if passwords are compromised. This
protection safeguards not only sensitive company and customer data but also
preserves customer trust and brand reputation, which are invaluable assets in
today’s digital economy. As remote and flexible work becomes standard, MFA
ensures secure access to company systems from any location, enabling
productivity without sacrificing security. Beyond risk reduction, MFA also
drives cost savings by minimizing fraud, security incidents, and IT support
overhead, while integrating seamlessly with existing identity management
systems to streamline operations and enhance efficiency. In essence, MFA is a
strategic investment that secures assets, supports modern work environments,
and protects your bottom line.</p>
<h1 id="authentication-methods">Authentication methods</h1>
<h2 id="why-multiple-options">Why multiple options</h2>
<p>Offering multiple MFA methods directly addresses both user experience and
operational resilience. Users have different preferences and access to
devices. Some may prefer the convenience of an authenticator app, while others
rely on SMS or biometrics. By providing choices, you reduce friction and
increase adoption rates, which is critical for widespread security compliance.
At the same time, redundancy ensures that if a user loses access to one method
(like a misplaced phone), they aren’t locked out of their account and can fall
back on an alternative, such as email verification or a hardware token. This
not only keeps productivity high but also aligns with industry best practices
and regulatory requirements, helping your product meet security standards
without sacrificing usability. In short, it’s about balancing strong security
with a seamless experience, which ultimately builds trust and reduces support
overhead. <a href="https://frontegg.com/blog/multi-factor-authentication-types">idpro-mfa-for-humans</a></p>
<h2 id="passkey-webauthn--fido2">Passkey (WebAuthn / FIDO2)</h2>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-|
| Factors  | - Something you <strong>have</strong> (device)   |
|          | - Somehting you <strong>know</strong> (PIN)      |</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>- Somethign you <strong>are</strong> (Biometric)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>Very High</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Passwordless</td>
      </tr>
      <tr>
          <td></td>
          <td>- Usernameless</td>
      </tr>
      <tr>
          <td></td>
          <td>- Phising resistant</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
  </tbody>
</table>
<p>Passkeys are a modern, user-friendly, and phishing-resistant authentication
method designed to replace passwords entirely. Built on WebAuthn and FIDO2
standards, passkeys enable passwordless and usernameless logins, relying
instead on cryptographic keys stored on the user’s device (e.g., smartphone,
laptop, or security key). They simplify the user experience by eliminating the
need to remember or enter credentials, while also providing stronger security
than traditional passwords.</p>
<p>The <code>AAGUID</code> (Authenticator Attestation GUID) identifies the passkey provider,
use this to display a user-friendly name (e.g., &ldquo;iPhone Passkey&rdquo; for better
clarity and management.</p>
<p><strong>Synced passkeys</strong> are stored encrypted in the cloud and automatically
synchronized across a user’s registered devices, such as through iCloud
Keychain or Google Password Manager. This allows users to log in passwordlessly
from any of their trusted devices, offering convenience and flexibility.</p>
<p>Essentially passkeys act like a direct interface between the server and the
password manager.</p>
<p><strong>Device-bound passkeys</strong> are permanently tied to a single device, such as a
smartphone, laptop, or <strong>hardware security key</strong>. They cannot be exported or
synced, providing stronger security by ensuring the private key never leaves
the device.</p>
<p>Hardware security keys could be provisioned and distributed amongst the users.
But this can be expense and time consuming. Most often companies choose to let
the user provision their own security key, then it can also be used to access
multiple services.</p>
<p>The most known hardware security key is the yubikey, but sold by many vendor
such as OneSpan.</p>
<h2 id="totp">TOTP</h2>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Something you <strong>have</strong> (device)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>Medium</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Commonly used</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;</td>
      </tr>
  </tbody>
</table>
<p>TOTP (Time-based One-Time Passcode) is a temporary, time-sensitive passcode
generated by an algorithm using the current time and a shared secret key. Each
code is valid only for a short period (usually 30 seconds), adding an extra
layer of security for authentication.</p>
<p>OATH (Initiative for Open Authentication) is an industry standard that defines
protocols for TOTP. It ensures compatibility and interoperability between
servers and authenticator apps. It is supported by all authenticator apps such as:</p>
<ul>
<li>Aegis Authenticator</li>
<li>Google Authenticator</li>
<li>Microsoft Authenticator</li>
</ul>
<p>To set up TOTP, users scan a QR code with their authenticator app and enter the
generated code to confirm it works. On mobile devices, since scanning a QR code
displayed on the same screen isn’t practical, use an <code>otpauth://</code> URL to
directly open and configure the authenticator app.</p>
<p>The authentication server should implement an <strong>OTP window</strong>, a setting to account
for clock synchronization differences. This improves user experience by
accepting codes generated in the previous, current, and next time intervals.
This flexibility accounts for minor clock differences between the server and
user device, reducing failed logins.</p>
<h2 id="sms-otp-one-time-passcode">SMS OTP (One time passcode)</h2>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Something you <strong>have</strong> (Phone with number)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>Low</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Commonly used</td>
      </tr>
      <tr>
          <td></td>
          <td>- No onboarding</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
  </tbody>
</table>
<p>SMS OTP (One-Time Password) is a widely used multi-factor authentication method
where a temporary, numeric code is sent to a user’s mobile phone via text
message after they enter their username and password. This code, typically 4–6
digits long, is valid for a short period (often a few minutes) and must be
entered into the login prompt to complete authentication.</p>
<p>Attackers may perform SIM swaps to intercept SMS-based OTP codes.</p>
<h2 id="email-otp">Email OTP</h2>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Something you <strong>have</strong> (access to mailbox)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>Very low</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Commonly used</td>
      </tr>
      <tr>
          <td></td>
          <td>- No onboarding</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
  </tbody>
</table>
<p>Email OTP sends a one-time code to the user’s inbox for login verification.
If self service password reset is enabled, email OTP results in only one
factor.</p>
<p><strong>Magic links</strong> a passwordless authentication method that sends users an URL,
allowing them to log in securely by clicking the link instead of entering the
OTP code. Consider using this to improve user experience in combination with
the OTP code.</p>
<h2 id="mobile-app-push-notifications">Mobile App Push notifications</h2>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Something you <strong>have</strong> (smartphone with app)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>High</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Easy to use</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;</td>
      </tr>
  </tbody>
</table>
<p>Mobile App Push Notifications authenticate users by sending an approval push
notification to a smartphone app. This method is user-friendly, as it only
requires a tap to approve or deny login attempts. It also encourages app
adoption.</p>
<p>Attackers can use <strong>MFA fatigue attacks</strong> exploit push notifications by
overwhelming users with repeated authentication prompts until they accidentally
approve one.</p>
<h2 id="backup-security-codes">Backup security codes</h2>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Something you <strong>have</strong> (a note with the codes)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>Low</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Possible offline backup</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&ndash;</td>
      </tr>
  </tbody>
</table>
<p>Backup Security Codes are single-use, one-time passcodes (OTPs) provided as a
last-resort authentication method when other MFA options are unavailable. They
should be displayed only once, never sent via email, and users should be
allowed to regenerate them if needed. It’s best to notify users (via email
or SMS) whenever a backup code is used. However, these codes should be avoided
if alternative MFA methods are available, as users often do not store them
securely.</p>
<h2 id="external-authentication">External Authentication</h2>
<p>External authentication delegates user verification to a trusted third-party
service or identity provider (Idp).</p>
<h3 id="itsme">Itsme</h3>
<h3 id="belgian-eid">Belgian eID</h3>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-|
| Factors  | - Something you <strong>have</strong> (eID card) |</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th>- Something you <strong>know</strong> (PIN)</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>High</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- All Belgian citizens have one</td>
      </tr>
      <tr>
          <td></td>
          <td>- Validate identiy information</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
  </tbody>
</table>
<p>Authentication with Belgian eID cards is a secure method exclusively for
Belgian citizens, using their national electronic identity card. It requires a
card reader and the user’s PIN code, though many users forget or don’t know
their PIN. Web authentication relies on mutual TLS (mTLS), ensuring encrypted
communication between the card and the server. Organizations must maintain the
PKI infrastructure, including government-issued CA certificates and support for
evolving cryptographic schemes, to ensure compatibility and security.</p>
<h3 id="federation-with-the-company-idp">Federation with the company Idp</h3>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Depends on the Idp</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>High</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Very user friendly</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
  </tbody>
</table>
<p>Federation with a client’s company Identity Provider (IdP), such as Microsoft
Entra ID, allows users to authenticate directly through their organization’s
system. This setup enables <strong>Single Sign-On</strong> (SSO), making it user-friendly by
letting employees log in with their corporate credentials. Federation is
typically based on the user’s email domain, automatically redirecting them to
their company’s login portal. In OpenID Connect (OIDC), you can use the
<code>acr_values</code> parameter to request specific authentication assurance levels. A
direct link specific for the company should also be created so it can be shown
on the company&rsquo;s webportal.</p>
<h3 id="federation-with-de-facto-standard-and-social-idps">Federation with de facto standard and social Idp&rsquo;s</h3>
<p>|&mdash;&mdash;&mdash;-|&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-|</p>
<table>
  <thead>
      <tr>
          <th>Factors</th>
          <th>- Depends on the Idp</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Security</td>
          <td><strong>High</strong></td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
      <tr>
          <td>Features</td>
          <td>- Very user friendly</td>
      </tr>
      <tr>
          <td>&mdash;&mdash;&mdash;-</td>
          <td>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;-</td>
      </tr>
  </tbody>
</table>
<p>Federation with de facto standard and social IdPs (like GitHub, Google,
Microsoft, Facebook, or LinkedIn) lets users log in to your service using their
existing social or professional accounts.</p>
<h1 id="considerations-when-implementing-mfa">Considerations when implementing MFA</h1>
<p>Temporarily trust a device for a set number of days to skip MFA prompts.</p>
<ul>
<li>Trusted Browsers: Use a secure cookie to maintain trust.</li>
<li>Mobile Apps: Store an OIDC refresh token securely, avoiding indefinite reuse.</li>
<li>Desktop Apps: Trust mechanisms vary by implementation.</li>
</ul>
<h2 id="registration">Registration</h2>
<p>If MFA is mandatory, provide a simple, step-by-step setup wizard to guide users
through the configuration process.</p>
<h2 id="managing-mfa-methods">Managing MFA methods</h2>
<p>Enable users to manage their authentication methods through self service. They
should be able to view their recent logins, including location, IP, and method
used, as well as see when each authentication method was created and last used,
for example, &ldquo;Passkey (Windows): Created on 2025-10-13 00:11, last used on
2025-10-13 00:11.&rdquo;</p>
<p>Allow users to add, reset, or remove authentication methods, and ensure they
can clearly see which account they are modifying by displaying their username,
email, and other account information. Before permitting any changes, verify the
user’s identity with a high level of assurance.</p>
<p>Support the creation of multiple authentication methods of the same type, such
as several authenticator apps or passkeys, to provide flexibility and backup
options.</p>
<h2 id="password-reset">Password reset</h2>
<p>Don&rsquo;t forget to aks for a second factor after letting the user reset their
password. This prevents malicious actors from gaining access to an account by
doing a password reset.</p>
<h2 id="helpdesk-support">Helpdesk support</h2>
<p>Allow helpdesk to help a user get access to their account. But avoid social
engineering attacks. Make sure that the user is thoroughly identified by the
helpdesk.</p>
<h2 id="audit-logging">Audit logging</h2>
<p>Robust MFA audit logging is essential. Track when users <strong>add</strong> or <strong>use</strong> an
authentication method, capturing key details like time, device, IP, location,
and method type. This visibility helps detect anomalies, supports compliance,
and enables quick incident response.</p>
<h2 id="consider-setup-up-authentication">Consider setup up authentication</h2>
<p>To improve user experience we don&rsquo;t have to ask the user to authenticate with
multiple factors during their initial login. We can provide limit access to the
application with an easy to use method such as a simple password, magic link or
trusted device. But only show less sensitive data and allow limited actions. If
the user want&rsquo;s to take sensitive actions, we can increase or &lsquo;set up&rsquo; our
assurance level by requesting that the user authenticates using a second
factor.</p>
<p>Ideally the fine grained authorization policy engine can handle policies where
a certain assurance level is required. In OIDC the <code>amr</code> and <code>acr</code> claims can
be used to check te assurance level.</p>
<h1 id="rollout">Rollout</h1>
<p>A phased rollout of multi-factor authentication (MFA) ensures a smoother, more
effective implementation by allowing users to adapt gradually, reducing the
risk of disruptions, and giving your IT and support teams the bandwidth to
address issues as they arise. Starting with high-priority systems or user
groups lets you focus resources where they’re needed most, while gathering
feedback at each stage helps refine the process before wider adoption. This
approach not only minimizes operational risks and user resistance but also
ensures that security improvements are sustainable and aligned with both
business needs and user experience. Ultimately, it’s about achieving strong
security without compromising productivity or overwhelming your teams.</p>
<h2 id="prepartion">Prepartion</h2>
<p>When preparing for an MFA rollout, it is important to:</p>
<p>Ensure each user has only one account to avoid confusion or duplication. Verify
that user contact details, such as phone numbers and email addresses, are
accurate and up to date. Confirm that your Identity and Access Management (IAM)
system fully supports the authentication methods you plan to implement.</p>
<h2 id="phase-0-enable-mfa">Phase 0: Enable MFA</h2>
<h2 id="phase-1-focus-group">Phase 1: Focus group</h2>
<p>Learn lessons to improve user experience.</p>
<h2 id="phase-2a-recommend-mfa-for-critical-accounts">Phase 2a: Recommend MFA for critical accounts</h2>
<h2 id="phase-2b-enforce-mfa-for-critical-accounts">Phase 2b: Enforce MFA for critical accounts</h2>
<h2 id="phase-3a-recommend-mfa-for-everyone--phase-3b-enforce-mfa-for-everyone">Phase 3a: Recommend MFA for everyone ## Phase 3b: Enforce MFA for everyone</h2>
<h1 id="non-human-account-access-delegation">Non-human account access delegation</h1>
<p>Allow services to access API&rsquo;s on the users behalf using a dedicated API
security mechanism, preferably [[OAuth]]. Often people want to use automations,
the non-human service should not use the users credentials.</p>
<h1 id="sources">Sources</h1>
<p><a href="https://cheatsheetseries.owasp.org/cheatsheets/Multifactor_Authentication_Cheat_Sheet.html">https://cheatsheetseries.owasp.org/cheatsheets/Multifactor_Authentication_Cheat_Sheet.html</a>
<a href="https://www.cyber.gc.ca/en/guidance/steps-effectively-deploying-multi-factor-authentication-mfa-itsap00105">https://www.cyber.gc.ca/en/guidance/steps-effectively-deploying-multi-factor-authentication-mfa-itsap00105</a></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>My Security Prinicples &amp; Guidelines</title>
      <link>https://notes.robinvanhove.me/notes/security/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/security/</guid>
      <description>&lt;h2 id=&#34;principles&#34;&gt;Principles&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s first describe some principles that should in order of importance.&lt;/p&gt;
&lt;h3 id=&#34;1-pragmatic-security&#34;&gt;1. Pragmatic Security&lt;/h3&gt;
&lt;p&gt;When creating an API the primary goal is to solve a problem for a user or
organisation. But we don&amp;rsquo;t want to create new problems by introducing vulnerabilities.&lt;/p&gt;
&lt;p&gt;When designing or implementing a new feature always consider how it could be abused and
strive for security by design.&lt;/p&gt;
&lt;p&gt;Be pragmatic, solve problems don&amp;rsquo;t create new ones.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="principles">Principles</h2>
<p>Let&rsquo;s first describe some principles that should in order of importance.</p>
<h3 id="1-pragmatic-security">1. Pragmatic Security</h3>
<p>When creating an API the primary goal is to solve a problem for a user or
organisation. But we don&rsquo;t want to create new problems by introducing vulnerabilities.</p>
<p>When designing or implementing a new feature always consider how it could be abused and
strive for security by design.</p>
<p>Be pragmatic, solve problems don&rsquo;t create new ones.</p>
<h3 id="2-use-standards--frameworks">2. Use Standards &amp; Frameworks</h3>
<p>When it comes to security, many organisations face the same problems, luckily
as a result we can also use the same solutions. In the world of software
engineering we are blessed with great open standards organisations and
communities such as <a href="https://owasp.org/">OWASP</a>, <a href="https://www.ietf.org/">IETF</a>,
<a href="https://openid.net/">the OpenID Foundation</a>, and the many open source
communities.</p>
<p>When faced with a check if one of the tools you are using might already have a
solution or look online if there are no current best practices on how it can be
solved.</p>
<p>For example, the front-end framework you are using probably has a way to obtain
OAuth tokens, and don&rsquo;t implement JWT validation yourself, your API framework or
standard library probably has an implementation of
<a href="https://datatracker.ietf.org/wg/jose/documents/">JOSE</a> already.</p>
<p>But be ware of the third-party risk, don&rsquo;t just add any random library as a
dependency.</p>
<p>Using standards and frameworks ensures interoperability, not only internally
but also when working with vendors, partners and customers. It also ensures
that we use reviewed solutions and implementations.</p>
<h3 id="3-layered-security">3. Layered Security</h3>
<ul>
<li>ZTA</li>
<li>&hellip;</li>
</ul>
<hr>
<h2 id="guidelines">Guidelines</h2>
<h3 id="threat-model">Threat Model</h3>
<p>The <strong>first step</strong> when considering security for any project is to start with a
threat model. Don&rsquo;t know what threat modeling is? Take a look at the <a href="https://www.threatmodelingmanifesto.org/">Threat
Modeling Manifesto</a> which gives the
following definition.</p>
<blockquote>
<p>Threat modeling is analyzing representations of a system to highlight
concerns about security and privacy characteristics.</p>
</blockquote>
<p>The manifesto describes four questions to ask to start threat modeling.</p>
<ol>
<li>What are we working on? <em>(Create a model)</em></li>
<li>What can go wrong? <em>(Identify threats)</em></li>
<li>What are we going to do about it? <em>(Design &amp; implement mitigations)</em></li>
<li>Did we do a good enough job? <em>(Review &amp; repeat)</em></li>
</ol>
<p>Plenty has been written online about threat modeling, so there is no need to
explain it further in this note. But I would like to highlight the following.</p>
<h4 id="threat-modeling-as-a-team-activity-not-a-ciso-requirement">Threat modeling as a team activity, not a CISO requirement</h4>
<p>Threat modeling should be an activity practiced by the team designing and
implementing the system. It&rsquo;s a fundamental way of doing pragmatic security by
focussing on mitigating the threats that really matter.</p>
<p>Creating and discussing the potential threats your system faces is a great way
to get the team to think about security and have security by design.</p>
<p>Unfortunately a threat model is often seen as a requirement form the
CISO-office which might require a DFD-diagram and threat categorized with
STRIDE so they can check the checkbox on their compliance spreadsheet without
really caring about security. Threat modeling without involving the team is a
waste of time.</p>
<h4 id="model-your-way">Model your way</h4>
<p>Data-flow-diagrams DFD&rsquo;s and
<a href="https://web.archive.org/web/20180818182151/https://cloudblogs.microsoft.com/microsoftsecure/2009/08/27/the-threats-to-our-products/">STRIDE</a>
can be great tools, but if you already have other models of your system you
should not have to create a new digram form scratch.</p>
<h4 id="continuous-threat-modeling">Continuous Threat Modeling</h4>
<p>When adding a new endpoint or making changes to an existing one, make sure to
update your threat model. Threat modeling is a continuous activity and not a
one off.</p>
<h4 id="further-reading">Further reading</h4>
<ul>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Threat_Modeling_Cheat_Sheet.html">Threat Modeling - OWASP Cheat Sheet
Series</a></li>
<li><a href="https://www.threatmodelingmanifesto.org/">Threat Modeling Manifesto</a></li>
</ul>
<h3 id="pentest">Pentest</h3>
<p>Internet facing API&rsquo;s should always be pentested.</p>
<h3 id="monitoring--logging">Monitoring &amp; Logging</h3>
<p>Ideally a security operations center (SOC)</p>
<h3></h3>
<p>Secure your transport layer!</p>
<ul>
<li>TLS 1.2+</li>
<li>Check certificates</li>
<li>DNSSEC</li>
<li>Secure ciphers
<ul>
<li><a href="https://ciphersuite.info">https://ciphersuite.info</a></li>
</ul>
</li>
<li>HTSTS</li>
</ul>
<hr>
<h2 id="references">References</h2>
<ul>
<li><a href="https://owasp.org/API-Security/editions/2023/en/0x00-header/">OWASP API Security Top 10</a>
[1]: <a href="https://owasp.org/www-project-application-security-verification-standard/">OWASP Application Security Verification Standard (ASVS) | OWASP Foundation</a></li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/REST_Security_Cheat_Sheet.html">REST Security - OWASP Cheat Sheet Series</a></li>
<li><a href="https://cheatsheetseries.owasp.org/cheatsheets/Threat_Modeling_Cheat_Sheet.html">Threat Modeling - OWASP Cheat Sheet Series</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>OpenID Shared Signals Framework</title>
      <link>https://notes.robinvanhove.me/notes/openid_ssf/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/openid_ssf/</guid>
      <description></description>
      <content:encoded><![CDATA[]]></content:encoded>
    </item>
    
    <item>
      <title>Policy-Based Access control with data filters</title>
      <link>https://notes.robinvanhove.me/notes/pbac_data_filter/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/pbac_data_filter/</guid>
      <description>&lt;p&gt;In the classic XCAML based fine grained authorization ([[fga]]) architecture,
the &lt;em&gt;Policy Decision Point&lt;/em&gt; or PDP is responsible for deciding weather a subject
such as a user is allowed to do an action on a specific resource.&lt;/p&gt;
&lt;p&gt;But in many real world architecture this pattern is difficult to apply. Let&amp;rsquo;s
look the following simple example. We want to built an application that shows a
simple list of all documents a user has access to.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In the classic XCAML based fine grained authorization ([[fga]]) architecture,
the <em>Policy Decision Point</em> or PDP is responsible for deciding weather a subject
such as a user is allowed to do an action on a specific resource.</p>
<p>But in many real world architecture this pattern is difficult to apply. Let&rsquo;s
look the following simple example. We want to built an application that shows a
simple list of all documents a user has access to.</p>
<p>We could retrieve all documents from the datastore and ask the PDP whether our
user has access and only return those. But that has an obvious disadvantage.</p>
<p>The people over at OpenID AuthZen have proposed to a search API. Where instead
of searching in our datastore, we search in the PDP directly. Unfortunately
this approach makes it difficult or at least impractical to implement filters
by the applications such as search by document name.</p>
<p>In this case the PDP would also be responsible for pagination which may not be
preferred. Additionally the PDP would have to know about each resource and
their relevant attributes. In reality this is something stored in the datastore.</p>
<p>What we really need in practice are policy-based data filters. Where we ask the
PDP for a filter under which condition the user is allowed to access a
resource. We can then combine this authorization filter with any filer need by
the application logic to query the datastore.</p>
<h2 id="example-worked-out-in">Example worked out in</h2>
<p>[[opa_data_filter]]</p>
<h2 id="authzen-data-filter-api-draft">AuthZen Data Filter API draft</h2>
<p><a href="https://hackmd.io/@oidf-wg-authzen/HkLiZVdb1l">https://hackmd.io/@oidf-wg-authzen/HkLiZVdb1l</a></p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
