drop the one-time migration: seed the store from a leftover file once, leave the file
A leftover plaintext client secret is stored once with -cas=0 when the store holds none, so nothing rotates. A store value wins over a different file. The file is no longer read back, compared or removed, and the migration unit is gone.
This commit is contained in:
parent
2fc63d844b
commit
fcc9c8d0ba
1 changed files with 114 additions and 350 deletions
|
|
@ -323,7 +323,6 @@ let
|
|||
onStdin = s: puts s != [ ] && lib.all (l: lib.hasInfix "value=-" l) (puts s);
|
||||
in
|
||||
onStdin (inAuthelia secretPublisherHere).systemd.services.authelia-swarm-secrets.script
|
||||
&& onStdin (inAuthelia secretPublisherHere).systemd.services.authelia-swarm-client-secrets.script
|
||||
&& !(onStdin "printf '%s' \"$secret\" | bao kv put -cas=0 x value=\"$secret\"")
|
||||
&& !(onStdin "# kv put x value=-\nbao kv put x value=@/tmp/f")
|
||||
&& onStdin "printf '%s' \"$secret\" | bao kv put -cas=0 x value=-";
|
||||
|
|
@ -369,8 +368,6 @@ let
|
|||
&& !(lib.hasInfix "bao kv" (lib.head (lib.splitString "bao login" c)));
|
||||
in
|
||||
holdsTokenFirst (inAuthelia secretPublisherHere).systemd.services.authelia-swarm-secrets.script
|
||||
&& holdsTokenFirst (inAuthelia secretPublisherHere)
|
||||
.systemd.services.authelia-swarm-client-secrets.script
|
||||
&& holdsTokenFirst (inAuthelia secretPublisherHere).systemd.services.swarm-authelia-bridge.preStart
|
||||
&& holdsTokenFirst baoWithMatrix.systemd.services.swarm-bao-matrix-oidc.script
|
||||
# Controls, so a clean verdict above means something. In order: a bare
|
||||
|
|
@ -389,24 +386,24 @@ let
|
|||
# would have left the unit rendering only on the one deployment that has
|
||||
# no use for it. It runs beside the mint, in authelia's container, and
|
||||
# never on the host.
|
||||
name = "the client secret migration holding an identity runs in authelia's container on a host with no store";
|
||||
name = "the mint holding an identity runs in authelia's container on a host with no store";
|
||||
ok =
|
||||
let
|
||||
m = secretPublisherRemote;
|
||||
c = inAuthelia m;
|
||||
in
|
||||
!m.services.hyperhive.deploy.bao.enable
|
||||
&& (c.systemd.services ? authelia-swarm-client-secrets)
|
||||
&& !(m.systemd.services ? authelia-swarm-client-secrets)
|
||||
&& lib.hasInfix "mint_client_secret" c.systemd.services.authelia-swarm-secrets.script
|
||||
&& !(m.systemd.services ? authelia-swarm-secrets)
|
||||
# Control: the host's own unit set is the one read above.
|
||||
&& (m.systemd.services ? "container@swarm-authelia");
|
||||
}
|
||||
{
|
||||
# What makes the arm above able to fail. Without a certificate the
|
||||
# plaintext has no store to go to, so the mint keeps it in a file beside
|
||||
# the digest as before, the migration does not exist, the bridge reads
|
||||
# the digest as before, the bridge reads
|
||||
# that file, and nspawn gets no credential to load.
|
||||
name = "an IdP host with no store identity keeps the client secrets in files and renders no migration";
|
||||
name = "an IdP host with no store identity keeps the client secrets in files";
|
||||
ok =
|
||||
let
|
||||
m = secretPublisherNoIdentity;
|
||||
|
|
@ -414,7 +411,6 @@ let
|
|||
mint = c.systemd.services.authelia-swarm-secrets.script;
|
||||
in
|
||||
m.services.hyperhive.deploy.authelia.enable
|
||||
&& !(c.systemd.services ? authelia-swarm-client-secrets)
|
||||
&& lib.hasInfix "mint() {" mint
|
||||
&& !(lib.hasInfix "mint_client_secret" mint)
|
||||
&&
|
||||
|
|
@ -423,7 +419,6 @@ let
|
|||
&& !(c.systemd.services.swarm-authelia-bridge.serviceConfig ? RuntimeDirectory)
|
||||
&& !(lib.any (lib.hasPrefix "--load-credential=") m.containers.swarm-authelia.extraFlags)
|
||||
# Controls: with an identity, the same lookups find the other shape.
|
||||
&& ((inAuthelia secretPublisherHere).systemd.services ? authelia-swarm-client-secrets)
|
||||
&& lib.hasInfix "mint_client_secret" (
|
||||
(inAuthelia secretPublisherHere).systemd.services.authelia-swarm-secrets.script
|
||||
)
|
||||
|
|
@ -456,20 +451,16 @@ let
|
|||
&& lib.hasInfix "client_secret_read ${leaf}" bridge.preStart
|
||||
&& lib.hasInfix "mint_client_secret swarm-authelia-bridge ${leaf}" here.systemd.services.authelia-swarm-secrets.script
|
||||
&& lib.elem "publisher-bao-cert" bridge.serviceConfig.LoadCredential
|
||||
&& bridge.serviceConfig.Restart == "on-failure"
|
||||
# The file it reads from is the one the earlier release left, until the
|
||||
# migration moves it into the store.
|
||||
&& lib.hasInfix "legacy=/var/lib/authelia-swarm/oidc-clients/swarm-authelia-bridge.secret" bridge.preStart;
|
||||
&& bridge.serviceConfig.Restart == "on-failure";
|
||||
}
|
||||
{
|
||||
# Every non-native client is migrated and minted at the leaf its reader
|
||||
# Every non-native client is minted at the leaf its reader
|
||||
# fetches, not only the ones with a reader in the publisher's list: the
|
||||
# bridge's own, which only the bridge reads, is the one that list lacks.
|
||||
name = "the migration visits every client at the leaf the mint creates, and a failure that no retry changes is not retried";
|
||||
name = "the mint stores every client at the leaf its reader fetches";
|
||||
ok =
|
||||
let
|
||||
c = inAuthelia secretPublisherHere;
|
||||
migrate = c.systemd.services.authelia-swarm-client-secrets;
|
||||
mint = c.systemd.services.authelia-swarm-secrets;
|
||||
pairs = [
|
||||
"hive-h1 secret/swarm/hives/h1/oidc/client"
|
||||
|
|
@ -479,19 +470,11 @@ let
|
|||
"swarm-authelia-bridge secret/swarm/services/swarm-authelia-bridge/oidc/client"
|
||||
];
|
||||
in
|
||||
lib.all (
|
||||
p:
|
||||
lib.hasInfix "migrate_client_secret ${p}" migrate.script
|
||||
&& lib.hasInfix "mint_client_secret ${p}" mint.script
|
||||
) pairs
|
||||
# A native client is public: it has no secret to mint or move.
|
||||
&& !(lib.hasInfix "swarmctl" migrate.script)
|
||||
lib.all (p: lib.hasInfix "mint_client_secret ${p}" mint.script) pairs
|
||||
# A native client is public: it has no secret to mint.
|
||||
&& !(lib.hasInfix "mint_client_secret swarmctl" mint.script)
|
||||
&& migrate.serviceConfig.RestartPreventExitStatus == 3
|
||||
# The mint answers authelia's password prompt through a pty.
|
||||
&& lib.any (p: lib.hasPrefix "util-linux" (p.name or "")) mint.path
|
||||
&& migrate.serviceConfig.Restart == "on-failure"
|
||||
&& migrate.serviceConfig.Type == "oneshot";
|
||||
&& lib.any (p: lib.hasPrefix "util-linux" (p.name or "")) mint.path;
|
||||
}
|
||||
{
|
||||
# Every key authelia signs or encrypts with comes from the store, seeded
|
||||
|
|
@ -532,8 +515,8 @@ let
|
|||
name = "the store identity reaches authelia's container as system credentials";
|
||||
ok =
|
||||
let
|
||||
dir = "/run/credentials/authelia-swarm-client-secrets.service";
|
||||
unit = m: (inAuthelia m).systemd.services.authelia-swarm-client-secrets;
|
||||
dir = "/run/credentials/authelia-swarm-secrets.service";
|
||||
unit = m: (inAuthelia m).systemd.services.authelia-swarm-secrets;
|
||||
flags = m: m.containers.swarm-authelia.extraFlags;
|
||||
here = unit secretPublisherHere;
|
||||
in
|
||||
|
|
@ -566,33 +549,6 @@ let
|
|||
)
|
||||
&& (unit secretPublisherRemote).environment.BAO_CLIENT_CERT == "${dir}/publisher-bao-cert";
|
||||
}
|
||||
{
|
||||
# Authelia is the swarm's IdP and has to come up while the store is down.
|
||||
# Nothing it starts after or needs may be the migration, and the
|
||||
# migration may not order itself in front of authelia.
|
||||
name = "authelia does not wait for the client secret migration";
|
||||
ok =
|
||||
let
|
||||
c = inAuthelia secretPublisherHere;
|
||||
authelia = c.systemd.services.authelia-swarm;
|
||||
publisher = c.systemd.services.authelia-swarm-client-secrets;
|
||||
unit = "authelia-swarm-client-secrets.service";
|
||||
in
|
||||
!(lib.any (l: lib.elem unit (authelia.${l} or [ ])) [
|
||||
"after"
|
||||
"requires"
|
||||
"wants"
|
||||
"bindsTo"
|
||||
"requisite"
|
||||
])
|
||||
&& !(lib.any (l: lib.elem "authelia-swarm.service" (publisher.${l} or [ ])) [
|
||||
"before"
|
||||
"requiredBy"
|
||||
])
|
||||
# Controls: both lookups find the real units.
|
||||
&& authelia.serviceConfig ? ExecStart
|
||||
&& lib.elem "authelia-swarm-secrets.service" publisher.after;
|
||||
}
|
||||
];
|
||||
in
|
||||
runGroup "secret-publisher" cases
|
||||
|
|
|
|||
Loading…
Reference in a new issue