<?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>Notes on Robin&#39;s notebook</title>
    <link>https://notes.robinvanhove.me/notes/</link>
    <description>Recent content in Notes on Robin&#39;s notebook</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language><atom:link href="https://notes.robinvanhove.me/notes/index.xml" rel="self" type="application/rss+xml" />
    <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>
    
    <item>
      <title>Talks to watch later</title>
      <link>https://notes.robinvanhove.me/notes/talks/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://notes.robinvanhove.me/notes/talks/</guid>
      <description>&lt;h2 id=&#34;fosdem-2026&#34;&gt;FOSDEM 2026&lt;/h2&gt;
&lt;h3 id=&#34;main-track&#34;&gt;Main track&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; &lt;a href=&#34;https://fosdem.org/2026/schedule/event/L3BK7S-free-as-in-burned-out/&#34;&gt;Free as in Burned Out: Who Really Pays for Open Source?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; &lt;a href=&#34;https://fosdem.org/2026/schedule/event/FE7ULY-foss-in-times-of-war-scarcity-and-ai/&#34;&gt;FOSS in times of war, scarcity and (adversarial) AI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;defcon-33&#34;&gt;DEFCON 33&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; &lt;a href=&#34;https://www.youtube.com/watch?v=KeNBWILSlC4&#34;&gt;All your keyboards are belong to us!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;cosic-pqcsa-workshop-brussels-2026&#34;&gt;Cosic PQCSA Workshop Brussels 2026&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=fLcyN2SM1Tk&#34;&gt;https://www.youtube.com/watch?v=fLcyN2SM1Tk&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;ndc-copenhagen-2025&#34;&gt;NDC Copenhagen 2025&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; &lt;a href=&#34;https://www.youtube.com/watch?v=WRg13Ze_UpY&#34;&gt;(Azure) Modern Architecture 101 for New Engineers &amp;amp; Forgetful Experts - Jerry Nixon - NDC Copenhagen 2025&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <content:encoded><![CDATA[<h2 id="fosdem-2026">FOSDEM 2026</h2>
<h3 id="main-track">Main track</h3>
<ul>
<li><input disabled="" type="checkbox"> <a href="https://fosdem.org/2026/schedule/event/L3BK7S-free-as-in-burned-out/">Free as in Burned Out: Who Really Pays for Open Source?</a></li>
<li><input checked="" disabled="" type="checkbox"> <a href="https://fosdem.org/2026/schedule/event/FE7ULY-foss-in-times-of-war-scarcity-and-ai/">FOSS in times of war, scarcity and (adversarial) AI</a></li>
</ul>
<h2 id="defcon-33">DEFCON 33</h2>
<ul>
<li><input disabled="" type="checkbox"> <a href="https://www.youtube.com/watch?v=KeNBWILSlC4">All your keyboards are belong to us!</a></li>
</ul>
<h2 id="cosic-pqcsa-workshop-brussels-2026">Cosic PQCSA Workshop Brussels 2026</h2>
<p><a href="https://www.youtube.com/watch?v=fLcyN2SM1Tk">https://www.youtube.com/watch?v=fLcyN2SM1Tk</a></p>
<h2 id="ndc-copenhagen-2025">NDC Copenhagen 2025</h2>
<ul>
<li><input disabled="" type="checkbox"> <a href="https://www.youtube.com/watch?v=WRg13Ze_UpY">(Azure) Modern Architecture 101 for New Engineers &amp; Forgetful Experts - Jerry Nixon - NDC Copenhagen 2025</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
