docs: improve secrets documentation

This commit is contained in:
Johannes Kirschbauer
2024-04-26 10:44:14 +02:00
parent fc1bf17b9c
commit 6a484fef66
2 changed files with 459 additions and 4 deletions

View File

@@ -6,7 +6,7 @@ Clan utilizes the [sops](https://github.com/getsops/sops) format and integrates
This documentation will guide you through managing secrets with the Clan CLI
## 1. Initializing Secrets
## Initializing Secrets (Quickstart)
### Create Your Master Keypair
@@ -28,11 +28,11 @@ Generated age private key at '/home/joerg/.config/sops/age/keys.txt' for your us
Also add your age public key to the repository with 'clan secrets users add YOUR_USER age1wkth7uhpkl555g40t8hjsysr20drq286netu8zptw50lmqz7j95sw2t3l7' (replace YOUR_USER with your actual username)
```
!!! warning
!!! warning
Make sure to keep a safe backup of the private key you've just created.
If it's lost, you won't be able to get to your secrets anymore because they all need the master key to be unlocked.
!!! note
!!! note
It's safe to add any secrets created by the clan CLI and placed in your repository to version control systems like `git`.
### Add Your Public Key
@@ -41,7 +41,7 @@ Also add your age public key to the repository with 'clan secrets users add YOUR
clan secrets users add <your_username> <your_public_key>
```
!!! note
!!! note
Choose the same username as on your Setup/Source Machine that you use to control the deployment with.
Once run this will create the following files:
@@ -53,6 +53,137 @@ sops/
└── key.json
```
---
> If you followed the quickstart tutorial all necessary secrets are initialized at this point.
- Continue with [deploying machines](./machines.md)
- Learn about the [basics concept](#concept) of clan secrets
---
## Concept
The secrets system conceptually knows two different entities:
- **Machine**: consumes secrets
- **User**: manages access to secrets
**A Users** Can add or revoke machines' access to secrets.
**A machine** Can decrypt secrets that where encrypted specifically for that machine.
!!! Danger
**Always make sure at least one _User_ has access to a secret**. Otherwise you could lock yourself out from accessing the secret.
### Inherited implications
By default clan uses [sops](https://github.com/getsops/sops) through [sops-nix](https://github.com/Mic92/sops-nix) for managing its secrets which inherits some implications that are important to understand:
- **Public/Private keys**: Entities are identified via their public keys. Each Entity can use their respective private key to decrypt a secret.
- **Public keys are stored**: All Public keys are stored inside the repository
- **Secrets are stored Encrypted**: secrets are stored inside the repository encrypted with the respective public keys
- **Secrets are deployed encrypted**: Fully encrypted secrets are deployed to machines at deployment time.
- **Secrets are decrypted by sops on-demand**: Each machine decrypts its secrets at runtime and stores them at an ephemeral location.
- **Machine key-pairs are auto-generated**: When a machine is created **no user-interaction is required** to setup public/private key-pairs.
- **secrets are re-encrypted**: In case machines, users or groups are modified secrets get re-encrypted on demand.
!!! Important
After revoking access to a secret you should also change the underlying secret. i.e. change the API key, or the password.
---
### Machine and user keys
The following diagrams illustrates how a user can provide a secret (i.e. a Password).
- By using the **Clan CLI** a user encrypts the password with both the **User public-key** and the **machine's public-key**
- The *Machine* can decrypt the password with its private-key on demand.
- The *User* is able to decrypt the password to make changes to it.
```plantuml
@startuml
!include C4_Container.puml
Person(user, "User", "Someone who manages secrets")
ContainerDb(secret, "Secret")
Container(machine, "Machine", "A Machine. i.e. Needs the Secret for a given Service." )
Rel_R(user, secret, "Encrypt", "", "Pubkeys: User, Machine")
Rel_L(secret, user, "Decrypt", "", "user privkey")
Rel_R(secret, machine, "Decrypt", "", "machine privkey" )
@enduml
```
### Groups
It is possible to create semantic groups to make access control more convenient.
#### User groups
Here we illustrate how machine groups work.
Common use cases:
- **Shared Management**: Access among multiple users. I.e. a subset of secrets/machines that have two admins
```plantuml
@startuml
!include C4_Container.puml
System_Boundary(c1, "Group") {
Person(user1, "User A", "has access")
Person(user2, "User B", "has access")
}
ContainerDb(secret, "Secret")
Container(machine, "Machine", "A Machine. i.e. Needs the Secret for a given Service." )
Rel_R(c1, secret, "Encrypt", "", "Pubkeys: User A, User B, Machine")
Rel_R(secret, machine, "Decrypt", "", "machine privkey" )
@enduml
```
<!-- TODO: See also [Groups Reference](#groups-reference) -->
---
#### Machine groups
Here we illustrate how machine groups work.
Common use cases:
- **Shared secrets**: Among multiple machines such as Wifi passwords
```plantuml
@startuml
!include C4_Container.puml
!include C4_Deployment.puml
Person(user, "User", "Someone who manages secrets")
ContainerDb(secret, "Secret")
System_Boundary(c1, "Group") {
Container(machine1, "Machine A", "Both machines need the same secret" )
Container(machine2, "Machine B", "Both machines need the same secret" )
}
Rel_R(user, secret, "Encrypt", "", "Pubkeys: machine A, machine B, User")
Rel(secret, c1, "Decrypt", "", "Both machine A or B can decrypt using their private key" )
@enduml
```
<!-- TODO: See also [Groups Reference](#groups-reference) -->
---
## 2. Adding Machine Keys
New machines in Clan come with age keys stored in `./sops/machines/<machine_name>`. To list these machines: