mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Add design diagrams (#2332)
This commit is contained in:
parent
bdb39332e3
commit
38f930c981
|
@ -66,8 +66,10 @@
|
|||
- [Design Documents]()
|
||||
- [Access Profiles 2022](developers/designs/access_profiles_rework_2022.md)
|
||||
- [Access Profiles Original](developers/designs/access_profiles_and_security.md)
|
||||
- [Access Control Defaults](developers/designs/access_control_defaults.md)
|
||||
- [Architecture](developers/designs/architecture.md)
|
||||
- [Authentication flow](developers/designs/authentication_flow.md)
|
||||
- [Domain Join](developers/designs/domain_join.md)
|
||||
- [Elevated Priv Mode](developers/designs/elevated_priv_mode.md)
|
||||
- [Oauth2 Refresh Tokens](developers/designs/oauth2_refresh_tokens.md)
|
||||
- [Replication Coordinator](developers/designs/replication_coord.md)
|
||||
|
|
162
book/src/developers/designs/access_control_defaults.md
Normal file
162
book/src/developers/designs/access_control_defaults.md
Normal file
|
@ -0,0 +1,162 @@
|
|||
# Access Control Defaults
|
||||
|
||||
- Do we need some kind of permission atoms to allow certain tasks?
|
||||
|
||||
## Use Cases:
|
||||
|
||||
- User sign-up portal (need service account that can create users and do cred reset)
|
||||
- Role for service account generation.
|
||||
- Remote backup - this account should be able to trigger and retrieve a backup
|
||||
- Groups should be able to be changed by a managing group (managed by)
|
||||
- IP limits on accounts?
|
||||
|
||||
- Users need to not be able to see other users.
|
||||
- Means the user can't read member attr, but can see groups + group info.
|
||||
|
||||
- Anonymous needs to be able to be blocked more easily.
|
||||
- Enable disable self-mail write
|
||||
- Enable disable self-name-change
|
||||
|
||||
## To achieve
|
||||
|
||||
- IP access limits
|
||||
- Managed By rules
|
||||
- Better group specification syntax (not filters)
|
||||
|
||||
## Domain Admin
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
DomainAdmin("Domain Admin") --> AccessControlAdmin("Access Control Admin")
|
||||
DomainAdmin("Domain Admin") --> AccountPolicyAdmin("Account Policy Admin")
|
||||
DomainAdmin("Domain Admin") --> DomainConfigAdmin("Domain Config Admin")
|
||||
DomainAdmin("Domain Admin") --> HPGroupAdmin("HP Group Admin")
|
||||
DomainAdmin("Domain Admin") --> SchemaAdmin("Schema Admin")
|
||||
DomainAdmin("Domain Admin") --> SyncAccountAdmin("Sync Account Admin")
|
||||
```
|
||||
|
||||
## IDM Admin
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
IdmAdmin("IDM Admin") --> GroupAdmin("Group Admin")
|
||||
IdmAdmin("IDM Admin") --> PersonAdmin("Person Admin")
|
||||
IdmAdmin("IDM Admin") --> PersonPIIModify("Person PII Modify")
|
||||
IdmAdmin("IDM Admin") --> PersonReadNoPII("Person Read No PII")
|
||||
IdmAdmin("IDM Admin") --> PosixAccountIncludesCredMod("POSIX Account - [Includes Cred Mod]")
|
||||
IdmAdmin("IDM Admin") --> RadiusAccountModify("Radius Account Modify")
|
||||
```
|
||||
|
||||
## Integration Admin
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
IntegrationAdmin("Integration Admin") --> Oauth2Admin("Oauth2 Admin")
|
||||
IntegrationAdmin("Integration Admin") --> PosixAccountConsumer("POSIX Account Consumer")
|
||||
IntegrationAdmin("Integration Admin") --> RadiusServiceAdmin("Radius Service Admin")
|
||||
```
|
||||
|
||||
## Help Desk
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
HelpDesk("Help Desk") --> PersonCredentialModify("Person Credential Modify")
|
||||
HelpDesk("Help Desk") --> PersonReadNoPII("Person Read No PII")
|
||||
```
|
||||
|
||||
## Account "Self"
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
SelfMailModify("Self Mail Modify") --> |"Modifies"| Self
|
||||
SelfRead("Self Read") --> |"Read"| Self
|
||||
SelfModify("Self Modify") --> |"Writes Secrets"| Self
|
||||
SelfNameModify("Self Name Modify") --> |"Modifies"| Self
|
||||
```
|
||||
|
||||
## Account-Related
|
||||
|
||||
Duplicated for Service Accounts, HP persons, HP service Accounts.
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
PersonOnBoard("Person On Board") --> |"Creates"| Persons("Persons")
|
||||
PersonAdmin("Person Admin") --> |"Creates Deletes"| Persons("Persons")
|
||||
PersonPIIModify --> |"Reads Modifies"| Persons
|
||||
PersonPIIModify("Person PII Modify") -.-> |"Member of"| PersonAdmin
|
||||
PersonCredentialModify("Person Credential Modify") -.-> |"Member of"| PersonAdmin
|
||||
PersonCredentialModify("Person Credential Modify") -.-> |"Member of"| PersonOnBoard
|
||||
PersonCredentialModify --> |"Reads Modifies"| Persons
|
||||
PersonCredentialModify --> |"Reads"| PersonReadNoPII("Person Read No PII")
|
||||
PersonAdmin --> PersonReadWithPII("Person Read - With PII")
|
||||
PersonReadWithPII --> PersonReadNoPII
|
||||
PersonReadNoPII --> |"Reads"| Persons
|
||||
PosixAccountIncludesCredMod --> |"Extends (Add Posix Account)"| Persons
|
||||
```
|
||||
|
||||
## Domain and Schema
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
DomainConfigAdmin("Domain Configuration Admin") --> |"Modifies Reads"| Domain
|
||||
DomainConfigAdmin("Domain Configuration Admin") --> |"Modifies Reads"| System
|
||||
SyncAccountAdmin("Sync Account Admin") --> |"Creates Modifies Deletes"| SyncAccounts("Sync Accounts")
|
||||
SchemaAdmin("Schema Admin") --> |"Creates Modifies"| Schema("Schema")
|
||||
AccessControlAdmin("Access Control Admin") --> |"Creates Modifies Deletes"| AccessControls("Access Controls")
|
||||
```
|
||||
|
||||
## High-Priv and Groups
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
GroupAdmin("Group Admin") --> |"Create Modify Delete"| Groups("Groups")
|
||||
AccountPolicyAdmin("Account Policy Admin") --> |"Modifies Extends"| Groups("Groups")
|
||||
GroupAdmin --> |"Modify Delete"| HPGroups("HP Groups")
|
||||
GroupAdmin --> |"Add Members"| HPGroup("HP Group")
|
||||
|
||||
HPGroupAdmin("HP Group Admin") --> HPGroup
|
||||
GroupAdmin -.-> |"Inherits"| HPGroupAdmin
|
||||
```
|
||||
|
||||
## OAuth2 Specific
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
Oauth2Admin("Oauth2 Admin") --> |"Creates Modifies Delegates"| Oauth2RS("Oauth2 RS")
|
||||
ScopedMember("Scoped Member") --> |"Reads"| Oauth2RS
|
||||
```
|
||||
|
||||
## POSIX-Specific
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
PosixAccountConsumer("POSIX Account Consumer") --> |"Reads Auths"| PosixAccounts("Posix Accounts")
|
||||
```
|
||||
|
||||
## Radius
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
RadiusServiceAdmin("Radius Service Admin") --> |"Adds Members"| RadiusService("Radius Service")
|
||||
RadiusService --> |"Reads Secrets"| RadiusAccounts("Radius Accounts")
|
||||
RadiusAccountModify("Radius Account Modify") --> |"Writes Secrets"| RadiusAccounts
|
||||
```
|
||||
|
||||
## Recycle Bin Admin
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
|
||||
RecycleBinAdmin("Recycle Bin Admin") --> |"Modifies Reads Revives"| RecycledEntries("Recycled Entries")
|
||||
```
|
128
book/src/developers/designs/domain_join.md
Normal file
128
book/src/developers/designs/domain_join.md
Normal file
|
@ -0,0 +1,128 @@
|
|||
# Domain Join - Machine Accounts
|
||||
|
||||
There are a number of features we have been considering that will require us to finally give in and
|
||||
support machine accounts also know as domain joining.
|
||||
|
||||
## Feature Requirements
|
||||
|
||||
### Limiting Unix Password Auth
|
||||
|
||||
Currently unix password authentication is targetted as the method for sudo. Initial access to the
|
||||
machine should come from ssh keys (and in future, ctap2).
|
||||
|
||||
In order to maintain compatability with LDAP style authentication, we allow "anonymous hosts" to
|
||||
retrieve ssh public keys, and then perform sudo authentication.
|
||||
|
||||
This has the obvious caveat that anyone can stand up a machine that trusts a Kanidm instance. This
|
||||
presents a double edged sword:
|
||||
|
||||
- By configuring a machine to authenticate via Kanidm, there is full trust
|
||||
in the authentication decisions Kanidm makes.
|
||||
- Users of Kanidm may be tricked into accessing a machine that is not managed
|
||||
by their IT or other central authority.
|
||||
|
||||
To prevent this, UNIX authentication should be configurable to prevent usage from unregistered machines.
|
||||
This will require the machine to present machine authentication credentials simultaneously with the
|
||||
user's credentials.
|
||||
|
||||
A potential change is removing the current unix password auth mechanism as a whole. Instead the
|
||||
user's auth token would contain a TPM bound credential that only the domain joined machine's TPM could
|
||||
access and use.
|
||||
|
||||
### Requesting Cryptographic Credentials
|
||||
|
||||
When a user logs in to a machine, it may be required that they can use that authentication to
|
||||
identify themself to other systems. When a user authenticates with credentials such as ssh-keys,
|
||||
it's not possible to use these to request other forwardable credentials - and ssh agent forwarding
|
||||
only allows forwarding of ssh credentials, not other types of credentials that may be needed.
|
||||
|
||||
In this case when a user authenticates with SSH, since they're using a trusted machine, Kanidm can
|
||||
request short-term and limited credentials on the users behalf.
|
||||
|
||||
An example is that we could dynamically request TLS certificates or Kerberos credentials.
|
||||
|
||||
Normally with ssh in this manner, everything has to use kerberos. This would force users to kinit on
|
||||
their machine to ssh and forward their credentials to the next machine. This causes friction since
|
||||
configuring kerberos on machines is an exercise in frustration, and with BYOD it gets even worse. In
|
||||
addition when using ssh with an ssh key, the only viable kinit mechanism is password or password +
|
||||
totp once the user has logged in. This is because pkcs11 can't be forwarded over ssh, nor can CTAP2,
|
||||
limiting kinit to weaker authentication mechanisms.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- Anonymous joins should not be allowed or permitted.
|
||||
- Join tokens need to be revoked (causing related machines to request re-enrollment) or expired
|
||||
(related machines can continue to function)
|
||||
- Join tokens must be auditable.
|
||||
- Private keys SHOULD be stored in a TPM, or at least a software HSM with a secured unlock key.
|
||||
- The use of the private key must prevent replay attacks
|
||||
|
||||
## Overview
|
||||
|
||||
Since the machine would now be an entity requiring authentication, we need to have a process to
|
||||
establish and maintain this trust relationship.
|
||||
|
||||
1. A join token is created by a user who is authorised to perform domain joins.
|
||||
2. The machine is audited for a known trust state. This process may vary from site to site. A future
|
||||
improvement could be that the join token can only release on certain TPM PCR values.
|
||||
3. The join token is yielded to the Kanidm UNIX daemon which submits its signing key to the Kanidm
|
||||
server.
|
||||
4. The kanidm server verifies the submission and creates a machine account.
|
||||
5. The kanidm unix daemon now uses it's signing key to sign a challenge that is submitted with all
|
||||
requests to the kanidm server.
|
||||
|
||||
Extra
|
||||
|
||||
6. Machines should be able to "re-join" with an alternate join token, moving their machine account
|
||||
join token relationship.
|
||||
7. Machines must be able to self-enroll newer keys which may have stronger cryptographic
|
||||
requirements.
|
||||
|
||||
## Details
|
||||
|
||||
### Join Token Creation
|
||||
|
||||
Join tokens are persisted in the database allowing tracing back to the usage of the token.
|
||||
|
||||
Every machine that is joined by that token will related back to that token. This allows auditing of
|
||||
which token was used to join which machine.
|
||||
|
||||
Machines may re-enroll with an alternate token.
|
||||
|
||||
The join token should be signed. The JWK pub key should be available at a known HTTPS uri so that
|
||||
the client can use it to validate the join token and its content. This _may_ allow policy to be
|
||||
embedded into the join token for the client to self-adhere to in the join process.
|
||||
|
||||
### Machine Auditing
|
||||
|
||||
The machine should be audited to be in a secure state. It's not yet clear how to proceed here, but
|
||||
we should consider using TPM PCRs with secure boot to measure this and validate the machine state.
|
||||
|
||||
One possible way to achieve this could be with full disk encryption that is bound to secure boot and
|
||||
TPM PCRs. Kanidm-unixd could validate the same PCR's to start operating. The challenge here would be
|
||||
updates of the expected PCR values during a system update. Alternately, Kanidm could "assume" that
|
||||
if started, then the FDE must have passed and attestation of health "is out of scope" for us.
|
||||
|
||||
### Public Key Submission
|
||||
|
||||
The private key should be generated and stored in a TPM/HSM. If possible, we should also submit
|
||||
attestation of this.
|
||||
|
||||
The submission of the public key should prevent replays, and should sign either a nonce or the
|
||||
current time. The current time must be valid to within a number of seconds. The nonce must be
|
||||
created by the server.
|
||||
|
||||
The machine must submit its public key, the time value and the signature. This should accompany the
|
||||
join token.
|
||||
|
||||
If the signature is valid, and the join token is correct, then the machine is joined and has a
|
||||
machine account created. The machine account is linked to the join token.
|
||||
|
||||
### Machine Account
|
||||
|
||||
The machine account is a new form of account, similar to a service account. It should identify the
|
||||
machine, its hostname, and other properties. It should also contain the machine's public key id.
|
||||
|
||||
When the machine requests certain API's from Kanidm, it should submit signed requests that include
|
||||
the current time. The kid is used to find the machine account that is submitting the request. This
|
||||
then validates the identity of the caller, and then allows the action to proceed.
|
Loading…
Reference in a new issue