fix(swarm-authelia): guard bearerAuthz against a silent no-op on kind
Review found that nothing stopped `bearerAuthz = true` on an interactive client. `renderClient` reads the flag only in the machine branch, so the scope is never emitted: the client authenticates, is authorised for nothing, and the build is green. `kind` defaults to `interactive`, so it is reached by forgetting a field rather than by writing a wrong one — this module's own failure mode one level up. The other half of the review asked to relax the method assertion to accept `null`, on the strength of the option's doc calling `null` authelia's default. Measured instead: under `authelia.bearer.authz` authelia refuses the omission outright, so the assertion was right and the DOC was wrong. The doc now carries the exception, and the assertion message says null is refused rather than leaving a reader to infer it.
This commit is contained in:
parent
3895a1e21d
commit
94204ac82b
1 changed files with 33 additions and 1 deletions
|
|
@ -587,6 +587,15 @@ in
|
|||
a successful consent** — the login looks like it worked
|
||||
right up to the last hop, and neither the redirect nor
|
||||
the secret is at fault.
|
||||
|
||||
⚠️ `null` is NOT accepted on a client with `bearerAuthz`.
|
||||
Measured against authelia 4.39.20: under that scope the
|
||||
method must be *stated*: omitting it is refused with
|
||||
`must be configured as 'client_secret_basic', … but it's
|
||||
configured as` an empty string. The sentence above is
|
||||
true of an ordinary client and false of that one, which
|
||||
is exactly how a reviewer reads this option and concludes
|
||||
the assertion below is wrong.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -935,7 +944,30 @@ in
|
|||
+ ". A confidential client carrying authelia.bearer.authz must "
|
||||
+ "authenticate with client_secret_basic, client_secret_jwt or "
|
||||
+ "private_key_jwt. Notably client_secret_post is refused, and "
|
||||
+ "it is what an OAuth2 client library may reach for first.";
|
||||
+ "it is what an OAuth2 client library may reach for first. "
|
||||
+ "Leaving it null is refused too: authelia requires the method "
|
||||
+ "to be STATED under this scope rather than defaulted.";
|
||||
}
|
||||
# Nothing else stops `bearerAuthz` on an interactive client, and it
|
||||
# would silently do nothing: `renderClient` reads the flag only in
|
||||
# the `machine` branch, so the scope is simply never emitted and the
|
||||
# client authenticates fine while being authorised for nothing.
|
||||
#
|
||||
# That is this module's own failure mode one level up — a green
|
||||
# build and a grant that does not exist — and `kind` defaults to
|
||||
# `interactive`, so it is reached by FORGETTING a field rather than
|
||||
# by writing a wrong one.
|
||||
{
|
||||
assertion = lib.all (c: !c.bearerAuthz || c.kind == "machine") cfg.oidc.clients;
|
||||
message =
|
||||
"services.hyperhive.swarm.authelia.oidc.clients: "
|
||||
+ lib.concatStringsSep ", " (
|
||||
map (c: "client '${c.id}'") (lib.filter (c: c.bearerAuthz && c.kind != "machine") cfg.oidc.clients)
|
||||
)
|
||||
+ " sets bearerAuthz with kind != \"machine\". The scope is only "
|
||||
+ "emitted for machine clients, so this grants nothing while "
|
||||
+ "evaluating and deploying cleanly. A browser client has a user "
|
||||
+ "to authorise and does not need it.";
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue