kanidm/docs/stable/developers/designs/access_profiles_rework_2022.html
2023-03-05 22:59:20 +00:00

357 lines
26 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Access Profiles 2022 - Kanidm Administration</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="../../favicon.png">
<link rel="stylesheet" href="../../css/variables.css">
<link rel="stylesheet" href="../../css/general.css">
<link rel="stylesheet" href="../../css/chrome.css">
<link rel="stylesheet" href="../../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../../highlight.css">
<link rel="stylesheet" href="../../tomorrow-night.css">
<link rel="stylesheet" href="../../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<div id="body-container">
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var html = document.querySelector('html');
var sidebar = null;
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="../../intro.html"><strong aria-hidden="true">1.</strong> Introduction to Kanidm</a></li><li class="chapter-item expanded "><a href="../../installing_the_server.html"><strong aria-hidden="true">2.</strong> Installing the Server</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../choosing_a_domain_name.html"><strong aria-hidden="true">2.1.</strong> Choosing a Domain Name</a></li><li class="chapter-item expanded "><a href="../../prepare_the_server.html"><strong aria-hidden="true">2.2.</strong> Preparing for your Deployment</a></li><li class="chapter-item expanded "><a href="../../server_configuration.html"><strong aria-hidden="true">2.3.</strong> Server Configuration and Install</a></li><li class="chapter-item expanded "><a href="../../security_hardening.html"><strong aria-hidden="true">2.4.</strong> Platform Security Hardening</a></li><li class="chapter-item expanded "><a href="../../server_update.html"><strong aria-hidden="true">2.5.</strong> Server Updates</a></li></ol></li><li class="chapter-item expanded "><a href="../../client_tools.html"><strong aria-hidden="true">3.</strong> Client Tools</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../installing_client_tools.html"><strong aria-hidden="true">3.1.</strong> Installing client tools</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Administration</li><li class="chapter-item expanded "><a href="../../administrivia.html"><strong aria-hidden="true">4.</strong> Administration</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../accounts_and_groups.html"><strong aria-hidden="true">4.1.</strong> Accounts and Groups</a></li><li class="chapter-item expanded "><a href="../../posix_accounts.html"><strong aria-hidden="true">4.2.</strong> POSIX Accounts and Groups</a></li><li class="chapter-item expanded "><a href="../../backup_restore.html"><strong aria-hidden="true">4.3.</strong> Backup and Restore</a></li><li class="chapter-item expanded "><a href="../../database_maint.html"><strong aria-hidden="true">4.4.</strong> Database Maintenance</a></li><li class="chapter-item expanded "><a href="../../domain_rename.html"><strong aria-hidden="true">4.5.</strong> Domain Rename</a></li><li class="chapter-item expanded "><a href="../../monitoring.html"><strong aria-hidden="true">4.6.</strong> Monitoring the platform</a></li><li class="chapter-item expanded "><a href="../../password_quality.html"><strong aria-hidden="true">4.7.</strong> Password Quality and Badlisting</a></li><li class="chapter-item expanded "><a href="../../recycle_bin.html"><strong aria-hidden="true">4.8.</strong> The Recycle Bin</a></li></ol></li><li class="chapter-item expanded "><li class="part-title">Services</li><li class="chapter-item expanded "><a href="../../integrations/pam_and_nsswitch.html"><strong aria-hidden="true">5.</strong> PAM and nsswitch</a></li><li class="chapter-item expanded "><a href="../../ssh_key_dist.html"><strong aria-hidden="true">6.</strong> SSH Key Distribution</a></li><li class="chapter-item expanded "><a href="../../integrations/oauth2.html"><strong aria-hidden="true">7.</strong> Oauth2</a></li><li class="chapter-item expanded "><a href="../../integrations/ldap.html"><strong aria-hidden="true">8.</strong> LDAP</a></li><li class="chapter-item expanded "><a href="../../integrations/radius.html"><strong aria-hidden="true">9.</strong> RADIUS</a></li><li class="chapter-item expanded affix "><li class="part-title">Synchronisation</li><li class="chapter-item expanded "><a href="../../sync/concepts.html"><strong aria-hidden="true">10.</strong> Concepts</a></li><li class="chapter-item expanded "><a href="../../sync/freeipa.html"><strong aria-hidden="true">11.</strong> FreeIPA</a></li><li class="chapter-item expanded affix "><li class="part-title">Integration Examples</li><li class="chapter-item expanded "><a href="../../examples/k8s_ingress_example.html"><strong aria-hidden="true">12.</strong> Kubernetes Ingress</a></li><li class="chapter-item expanded "><a href="../../integrations/traefik.html"><strong aria-hidden="true">13.</strong> Traefik</a></li><li class="chapter-item expanded affix "><li class="part-title">Support</li><li class="chapter-item expanded "><a href="../../troubleshooting.html"><strong aria-hidden="true">14.</strong> Troubleshooting</a></li><li class="chapter-item expanded "><a href="../../frequently_asked_questions.html"><strong aria-hidden="true">15.</strong> Frequently Asked Questions</a></li><li class="chapter-item expanded "><a href="../../glossary.html"><strong aria-hidden="true">16.</strong> Glossary of Technical Terms</a></li><li class="chapter-item expanded affix "><li class="part-title">For Developers</li><li class="chapter-item expanded "><a href="../../DEVELOPER_README.html"><strong aria-hidden="true">17.</strong> Developer Guide</a></li><li class="chapter-item expanded "><a href="../../developers/faq.html"><strong aria-hidden="true">18.</strong> FAQ</a></li><li class="chapter-item expanded "><div><strong aria-hidden="true">19.</strong> Design Documents</div></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../developers/designs/access_profiles_rework_2022.html" class="active"><strong aria-hidden="true">19.1.</strong> Access Profiles 2022</a></li><li class="chapter-item expanded "><a href="../../developers/designs/access_profiles_and_security.html"><strong aria-hidden="true">19.2.</strong> Access Profiles Original</a></li><li class="chapter-item expanded "><a href="../../developers/designs/rest_interface.html"><strong aria-hidden="true">19.3.</strong> REST Interface</a></li><li class="chapter-item expanded "><a href="../../developers/designs/elevated_priv_mode.html"><strong aria-hidden="true">19.4.</strong> Elevated Priv Mode</a></li></ol></li><li class="chapter-item expanded "><a href="../../developers/python.html"><strong aria-hidden="true">20.</strong> Python Module</a></li><li class="chapter-item expanded "><a href="../../developers/radius.html"><strong aria-hidden="true">21.</strong> RADIUS Integration</a></li><li class="chapter-item expanded "><a href="../../packaging.html"><strong aria-hidden="true">22.</strong> Packaging</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../../packaging_debs.html"><strong aria-hidden="true">22.1.</strong> Debian/Ubuntu</a></li></ol></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Kanidm Administration</h1>
<div class="right-buttons">
<a href="../../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/kanidm/kanidm" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/kanidm/kanidm/edit/master/book/src/developers/designs/access_profiles_rework_2022.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="access-profiles-rework-2022"><a class="header" href="#access-profiles-rework-2022">Access Profiles Rework 2022</a></h1>
<p>Access controls are critical for a project like Kanidm to determine who can access what on other
entries. Our access controls have to be dynamic and flexible as administrators will want to define
their own access controls. In almost every call in the server, they are consulted to determine if
the action can be carried out. We also supply default access controls so that out of the box we are
a complete and useful IDM.</p>
<p>The original design of the access control system was intended to satisfy our need for flexibility,
but we have begun to discover a number of limitations. The design incorporating filter queries makes
them hard to administer as we have not often publicly talked about the filter language and how it
internally works. Because of their use of filters it is hard to see on an entry &quot;what&quot; access
controls will apply to entries, making it hard to audit without actually calling the ACP subsystem.
Currently the access control system has a large impact on performance, accounting for nearly 35% of
the time taken in a search operation.</p>
<p>Additionally, the default access controls that we supply have started to run into limits and rough
cases due to changes as we have improved features. Some of this was due to limited design with user
cases in mind during development.</p>
<p>To resolve this a number of coordinating features need implementation to improve this situation.
These features will be documented <em>first</em>, and the use cases <em>second</em> with each use case linking to
the features that satisfy it.</p>
<h2 id="required-features-to-satisfy"><a class="header" href="#required-features-to-satisfy">Required Features to Satisfy</a></h2>
<h3 id="refactor-of-default-access-controls"><a class="header" href="#refactor-of-default-access-controls">Refactor of default access controls</a></h3>
<p>The current default privileges will need to be refactored to improve separation of privilege and
improved delegation of finer access rights.</p>
<h3 id="access-profiles-target-specifiers-instead-of-filters"><a class="header" href="#access-profiles-target-specifiers-instead-of-filters">Access profiles target specifiers instead of filters</a></h3>
<p>Access profiles should target a list of groups for who the access profile applies to, and who
receives the access it is granting.</p>
<p>Alternately an access profile could target &quot;self&quot; so that self-update rules can still be expressed.</p>
<p>An access profile could target an oauth2 definition for the purpose of allowing reads to members of
a set of scopes that can access the service.</p>
<p>The access profile receiver would be group based only. This allows specifying that &quot;X group of
members can write self&quot; meaning that any member of that group can write to themself and only
themself.</p>
<p>In the future we could also create different target/receiver specifiers to allow other extended
management and delegation scenarioes. This improves the situation making things more flexible from
the current filter system. It also may allow filters to be simplified to remove the SELF uuid
resolve step in some cases.</p>
<h3 id="filter-based-groups"><a class="header" href="#filter-based-groups">Filter based groups</a></h3>
<p>These are groups who's members are dynamically allocated based on a filter query. This allows a
similar level of dynamic group management as we have currently with access profiles, but with the
additional ability for them to be used outside of the access control context. This is the &quot;bridge&quot;
allowing us to move from filter based access controls to &quot;group&quot; targeted.</p>
<p>A risk of filter based groups is &quot;infinite churn&quot; because of recursion. This can occur if you had a
rule such a &quot;and not memberof = self&quot; on a dynamic group. Because of this, filters on dynamic groups
may not use &quot;memberof&quot; unless they are internally provided by the kanidm project so that we can vet
these rules as correct and without creating infinite recursion scenarioes.</p>
<h3 id="access-rules-extracted-to-aci-entries-on-targets"><a class="header" href="#access-rules-extracted-to-aci-entries-on-targets">Access rules extracted to ACI entries on targets</a></h3>
<p>The access control profiles are an excellent way to administer access where you can specific whom
has access to what, but it makes it harder for the reverse query which is &quot;who has access to this
specific entity&quot;. Since this is needed for both search and auditing, by specifying our access
profiles in the current manner, but using them to generate ACE rules on the target entry will allow
the search and audit paths to answer the question of &quot;who has access to this entity&quot; much faster.</p>
<h3 id="sudo-mode"><a class="header" href="#sudo-mode">Sudo Mode</a></h3>
<p>A flag should exist on a session defining &quot;sudo&quot; mode which requires a special account policy
membership OR a re-authentication to enable. This sudo flag is a time window on a session token
which can allow/disallow certain behaviours. It would be necessary for all write paths to have
access to this value.</p>
<h3 id="account-policy"><a class="header" href="#account-policy">Account Policy</a></h3>
<p>Account policy defines rules on accounts and what they can or can't do with regard to properties and
authentication. This is required for sudo mode so that a group of accounts can be &quot;always in sudo&quot;
mode and this enforces rules on session expiry.</p>
<h2 id="access-control-use-cases"><a class="header" href="#access-control-use-cases">Access Control Use Cases</a></h2>
<h3 id="default-roles--separation-of-privilege"><a class="header" href="#default-roles--separation-of-privilege">Default Roles / Separation of Privilege</a></h3>
<p>By default we attempt to separate privileges so that &quot;no single account&quot; has complete authority over
the system.</p>
<p>Satisfied by:</p>
<ul>
<li>Refactor of default access controls</li>
<li>Filter based groups</li>
<li>Sudo Mode</li>
</ul>
<h4 id="system-admin"><a class="header" href="#system-admin">System Admin</a></h4>
<p>This role, also called &quot;admins&quot; is responsible to manage Kanidm as a service. It does NOT manage
users or accounts.</p>
<p>The &quot;admins&quot; role is responsible to manage:</p>
<ul>
<li>The name of the domain</li>
<li>Configuration of the servers and replication</li>
<li>Management of external integrations (oauth2)</li>
</ul>
<h4 id="service-account-admin"><a class="header" href="#service-account-admin">Service Account Admin</a></h4>
<p>The role would be called &quot;sa_admins&quot; and would be responsible for top level management of service
accounts, and delegating authority for service account administration to managing users.</p>
<ul>
<li>Create service accounts</li>
<li>Delegate service account management to owners groups</li>
<li>Migrate service accounts to persons</li>
</ul>
<p>The service account admin is capable of migrating service accounts to persons as it is &quot;yielding&quot;
control of the entity, rather than an idm admin &quot;taking&quot; the entity which may have security impacts.</p>
<h4 id="service-desk"><a class="header" href="#service-desk">Service Desk</a></h4>
<p>This role manages a subset of persons. The helpdesk roles are precluded from modification of &quot;higher
privilege&quot; roles like service account, identity and system admins. This is due to potential
privilege escalation attacks.</p>
<ul>
<li>Can create credential reset links</li>
<li>Can lock and unlock accounts and their expiry.</li>
</ul>
<h4 id="idm-admin"><a class="header" href="#idm-admin">Idm Admin</a></h4>
<p>This role manages identities, or more specifically person accounts. In addition in is a &quot;high
privilege&quot; service desk role and can manage high privilege users as well.</p>
<ul>
<li>Create persons</li>
<li>Modify and manage persons</li>
<li>All roles of service desk for all persons</li>
</ul>
<h3 id="self-write--write-privilege"><a class="header" href="#self-write--write-privilege">Self Write / Write Privilege</a></h3>
<p>Currently write privileges are always available to any account post-authentication. Writes should
only be available after an extra &quot;challenge&quot; or &quot;sudo&quot; style extra auth, and only have a limited
time window of usage. The write window can be extended during the session. This allows extremely
long lived sessions contrast to the current short session life. It also makes it safer to provide
higher levels of privilege to persons since these rights are behind a re-authentication event.</p>
<p>Some accounts should always be considered able to write, and these accounts should have limited
authentication sessions as a result of this.</p>
<p>Satisfied by:</p>
<ul>
<li>Access profiles target specifiers instead of filters</li>
<li>Sudo Mode</li>
</ul>
<h3 id="oauth2-service-read-nice-to-have"><a class="header" href="#oauth2-service-read-nice-to-have">Oauth2 Service Read (Nice to Have)</a></h3>
<p>For ux/ui integration, being able to list oauth2 applications that are accessible to the user would
be a good feature. To limit &quot;who&quot; can see the oauth2 applications that an account can access a way
to &quot;allow read&quot; but by proxy of the related users of the oauth2 service. This will require access
controls to be able to interpret the oauth2 config and provide rights based on that.</p>
<p>Satisfied by:</p>
<ul>
<li>Access profiles target specifiers instead of filters</li>
</ul>
<h3 id="administration"><a class="header" href="#administration">Administration</a></h3>
<p>Access controls should be easier to manage and administer, and should be group based rather than
filter based. This will make it easier for administrators to create and define their own access
rules.</p>
<ul>
<li>Refactor of default access controls</li>
<li>Access profiles target specifiers instead of filters</li>
<li>Filter based groups</li>
</ul>
<h3 id="service-account-access"><a class="header" href="#service-account-access">Service Account Access</a></h3>
<p>Service accounts should be able to be &quot;delegated&quot; administration, where a group of users can manage
a service account. This should not require administrators to create unique access controls for each
service account, but a method to allow mapping of the service account to &quot;who manages it&quot;.</p>
<ul>
<li>Sudo Mode</li>
<li>Account Policy</li>
<li>Access profiles target specifiers instead of filters</li>
<li>Refactor of default access controls</li>
</ul>
<h3 id="auditing-of-access"><a class="header" href="#auditing-of-access">Auditing of Access</a></h3>
<p>It should be easier to audit whom has access to what by inspecting the entry to view what can access
it.</p>
<ul>
<li>Access rules extracted to ACI entries on targets</li>
<li>Access profiles target specifiers instead of filters</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../../developers/faq.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../../developers/designs/access_profiles_and_security.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../../developers/faq.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../../developers/designs/access_profiles_and_security.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../../elasticlunr.min.js"></script>
<script src="../../mark.min.js"></script>
<script src="../../searcher.js"></script>
<script src="../../clipboard.min.js"></script>
<script src="../../highlight.js"></script>
<script src="../../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>