feat: finer-grained ACLs for server accesses
In the process of adding multi-tenant infrastructure, it seems relevant to add finer-grained ACLs. Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
This commit is contained in:
parent
1cbf286f18
commit
130faa2836
|
@ -1,16 +1,21 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
keys = import ./ssh-keys.nix;
|
||||
in {
|
||||
users.users.root.openssh.authorizedKeys.keys =
|
||||
keys.users.delroth ++
|
||||
keys.users.emilylange ++
|
||||
keys.users.hexchen ++
|
||||
keys.users.jade ++
|
||||
keys.users.janik ++
|
||||
keys.users.k900 ++
|
||||
keys.users.lukegb ++
|
||||
keys.users.maxine ++
|
||||
keys.users.raito ++
|
||||
keys.users.thubrecht ++
|
||||
keys.users.yuka;
|
||||
}
|
||||
inherit (lib) genAttrs;
|
||||
buildInfraMembers = [
|
||||
"delroth"
|
||||
"emilylange"
|
||||
"hexchen"
|
||||
"jade"
|
||||
"janik"
|
||||
"k900"
|
||||
"maxine"
|
||||
"raito"
|
||||
"thubrecht"
|
||||
"yuka"
|
||||
];
|
||||
in
|
||||
{
|
||||
bagel.admins.users = genAttrs buildInfraMembers (username: {
|
||||
groups = [ "build-infra" ];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
imports = [
|
||||
./admins.nix
|
||||
./server-acl.nix
|
||||
./base-server.nix
|
||||
./hardening.nix
|
||||
./nix.nix
|
||||
|
|
51
common/server-acl.nix
Normal file
51
common/server-acl.nix
Normal file
|
@ -0,0 +1,51 @@
|
|||
{ lib, config, ... }:
|
||||
let
|
||||
keys = import ./ssh-keys.nix;
|
||||
inherit (lib) mkOption types length filterAttrs any catAttrs concatLists attrValues;
|
||||
cfg = config.bagel.admins;
|
||||
userOpts = { name, ... }: {
|
||||
options = {
|
||||
groups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "List of groups this user is part of";
|
||||
example = [ "build-infra" ];
|
||||
default = [ ];
|
||||
};
|
||||
|
||||
sshKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
description = "List of SSH keys associated to this user, defaults to `ssh-keys.nix` entries.";
|
||||
default = keys.users.${name} or [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
isAllowedGroup = group: any (allowedGroup: group == allowedGroup) cfg.allowedGroups;
|
||||
rootKeys = concatLists (catAttrs "sshKeys" (attrValues (filterAttrs (username: { groups, ... }: any isAllowedGroup groups) cfg.users)));
|
||||
in
|
||||
{
|
||||
options.bagel.admins = {
|
||||
allowedGroups = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "catch-all" ];
|
||||
description = "List of groups which are allowed to admin this machine.";
|
||||
example = [ "lix" "build-infra" ];
|
||||
};
|
||||
|
||||
users = mkOption {
|
||||
type = types.attrsOf (types.submodule userOpts);
|
||||
description = "Attribute set of admins with their groups and credentials, the username is the key of the attrset";
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
assertions = [
|
||||
{ assertion = length config.users.users.root.openssh.authorizedKeys.keys > 0;
|
||||
# TODO: you can add printing of `concatStringsSep ", " cfg.allowedGroups` to diagnose
|
||||
# which are the allowed groups and existing admins.
|
||||
message = "root@${config.networking.fqdnOrHostName} has no SSH key attached, this machine will lose its access if you deploy it successfully! Set a valid `bagel.admins.allowedGroups` or ensure you have at least one administrator of the relevant group registered";
|
||||
}
|
||||
];
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = rootKeys;
|
||||
};
|
||||
}
|
Loading…
Reference in a new issue