diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index d23a729b2..67ef953a7 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -381,6 +381,18 @@ github = "mipmip"; githubId = 658612; }; + mokrinsky = { + name = "mokrinsky"; + email = "463907+mokrinsky@users.noreply.github.com"; + github = "mokrinsky"; + githubId = 463907; + keys = [ + { + longkeyid = "rsa4096/0x73CC011921471A15"; + fingerprint = "EA54 E892 D96C 779E 1FA6 4E0A 73CC 0119 2147 1A15"; + } + ]; + }; msfjarvis = { email = "me@msfjarvis.dev"; github = "msfjarvis"; diff --git a/modules/misc/news/2025/11/2025-11-05_14-54-50.nix b/modules/misc/news/2025/11/2025-11-05_14-54-50.nix new file mode 100644 index 000000000..8c5ef668a --- /dev/null +++ b/modules/misc/news/2025/11/2025-11-05_14-54-50.nix @@ -0,0 +1,9 @@ +{ + time = "2025-11-05T12:54:50+00:00"; + condition = true; + message = '' + A new module is available: 'programs.saml2aws'. + + saml2aws is a CLI tool which enables you to login and retrieve AWS temporary credentials using a SAML IDP. It support a bunch of SAML providers, from cloud ones like Akamai, Okta or OneLogin, to corporate or self-hosted like Authentik, KeyCloak or ADFS. + ''; +} diff --git a/modules/programs/saml2aws.nix b/modules/programs/saml2aws.nix new file mode 100644 index 000000000..1d7d9c364 --- /dev/null +++ b/modules/programs/saml2aws.nix @@ -0,0 +1,94 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.programs.saml2aws; + iniFormat = pkgs.formats.ini { }; + inherit (lib) mkIf mkOption types; +in +{ + meta.maintainers = [ lib.hm.maintainers.mokrinsky ]; + + options.programs.saml2aws = { + enable = lib.mkEnableOption "saml2aws CLI tool"; + + package = lib.mkPackageOption pkgs "saml2aws" { + default = "saml2aws"; + nullable = true; + }; + + enableBashIntegration = lib.hm.shell.mkBashIntegrationOption { + inherit config; + extraDescription = ''If enabled, this will install autocompletion for bash.''; + }; + + enableZshIntegration = lib.hm.shell.mkZshIntegrationOption { + inherit config; + extraDescription = ''If enabled, this will install autocompletion for zsh.''; + }; + + configLocation = mkOption { + default = "${config.home.homeDirectory}/.saml2aws"; + defaultText = lib.literalExpression ''"''${config.home.homeDirectory}/.saml2aws"''; + type = types.str; + example = lib.literalExpression ''"''${config.home.homeDirectory}/.config/.saml2aws"''; + description = '' + Environment variable to specify the location of saml2aws configuration. + ''; + }; + + credentials = mkOption { + type = types.submodule { freeformType = iniFormat.type; }; + default = { }; + example = lib.literalExpression '' + { + aws = { + name = "aws"; + url = "https://domain.tld/uri/of/your/auth/endpoint"; + username = "username"; + provider = "Authentik"; + mfa = "Auto"; + skip_verify = false; + timeout = 0; + aws_urn = "urn:amazon:webservices"; + aws_session_duration = 3600; + aws_profile = "123456789000"; + saml_cache = false; + disable_remember_device = false; + disable_sessions = false; + download_browser_driver = false; + headless = false; + }; + } + ''; + description = '' + Configuration written to {file}`$HOME/.saml2aws` or config.programs.saml2aws.configLocation. + ''; + }; + }; + + config = mkIf cfg.enable { + home = { + packages = mkIf (cfg.package != null) [ cfg.package ]; + + sessionVariables.SAML2AWS_CONFIGFILE = cfg.configLocation; + + file."${cfg.configLocation}" = mkIf (cfg.credentials != { }) { + source = iniFormat.generate "saml2aws-credentials-${config.home.username}" cfg.credentials; + }; + }; + + programs.bash.initExtra = mkIf cfg.enableBashIntegration '' + eval "$(${lib.getExe cfg.package} --completion-script-bash)" + ''; + + programs.zsh.initContent = mkIf cfg.enableZshIntegration '' + eval "$(${lib.getExe cfg.package} --completion-script-zsh)" + ''; + + }; +} diff --git a/tests/modules/programs/saml2aws/default.nix b/tests/modules/programs/saml2aws/default.nix new file mode 100644 index 000000000..c825eb852 --- /dev/null +++ b/tests/modules/programs/saml2aws/default.nix @@ -0,0 +1,3 @@ +{ + saml2aws = ./saml2aws.nix; +} diff --git a/tests/modules/programs/saml2aws/saml2aws.conf b/tests/modules/programs/saml2aws/saml2aws.conf new file mode 100644 index 000000000..be74c944a --- /dev/null +++ b/tests/modules/programs/saml2aws/saml2aws.conf @@ -0,0 +1,16 @@ +[aws] +aws_profile=123456789000 +aws_session_duration=3600 +aws_urn=urn:amazon:webservices +disable_remember_device=false +disable_sessions=false +download_browser_driver=false +headless=false +mfa=Auto +name=aws +provider=Authentik +saml_cache=false +skip_verify=false +timeout=0 +url=https://domain.tld/uri/of/your/auth/endpoint +username=username diff --git a/tests/modules/programs/saml2aws/saml2aws.nix b/tests/modules/programs/saml2aws/saml2aws.nix new file mode 100644 index 000000000..200f20d16 --- /dev/null +++ b/tests/modules/programs/saml2aws/saml2aws.nix @@ -0,0 +1,33 @@ +{ + programs = { + saml2aws = { + enable = true; + credentials = { + aws = { + name = "aws"; + url = "https://domain.tld/uri/of/your/auth/endpoint"; + username = "username"; + provider = "Authentik"; + mfa = "Auto"; + skip_verify = false; + timeout = 0; + aws_urn = "urn:amazon:webservices"; + aws_session_duration = 3600; + aws_profile = "123456789000"; + saml_cache = false; + disable_remember_device = false; + disable_sessions = false; + download_browser_driver = false; + headless = false; + }; + + }; + }; + }; + + nmt.script = '' + assertFileExists home-files/.saml2aws + assertFileContent home-files/.saml2aws \ + ${./saml2aws.conf} + ''; +}