lol

nixos/openbao: init, 2.2.0 -> 2.2.1 (#394995)

authored by

Ilan Joselevich and committed by
GitHub
b016a1c0 44180b34

+329 -27
+1
nixos/modules/module-list.nix
··· 1426 1426 ./services/security/nginx-sso.nix 1427 1427 ./services/security/oauth2-proxy.nix 1428 1428 ./services/security/oauth2-proxy-nginx.nix 1429 + ./services/security/openbao.nix 1429 1430 ./services/security/opensnitch.nix 1430 1431 ./services/security/paretosecurity.nix 1431 1432 ./services/security/pass-secret-service.nix
+160
nixos/modules/services/security/openbao.nix
··· 1 + { 2 + config, 3 + lib, 4 + pkgs, 5 + ... 6 + }: 7 + let 8 + cfg = config.services.openbao; 9 + 10 + settingsFormat = pkgs.formats.json { }; 11 + in 12 + { 13 + options = { 14 + services.openbao = { 15 + enable = lib.mkEnableOption "OpenBao daemon"; 16 + 17 + package = lib.mkPackageOption pkgs "openbao" { 18 + example = "pkgs.openbao.override { withHsm = false; withUi = false; }"; 19 + }; 20 + 21 + settings = lib.mkOption { 22 + description = '' 23 + Settings of OpenBao. 24 + 25 + See [documentation](https://openbao.org/docs/configuration) for more details. 26 + ''; 27 + example = lib.literalExpression '' 28 + { 29 + ui = true; 30 + 31 + listener.default = { 32 + type = "tcp"; 33 + tls_acme_email = config.security.acme.defaults.email; 34 + tls_acme_domains = [ "example.com" ]; 35 + tls_acme_disable_http_challenge = true; 36 + }; 37 + 38 + cluster_addr = "http://127.0.0.1:8201"; 39 + api_addr = "https://example.com"; 40 + 41 + storage.raft.path = "/var/lib/openbao"; 42 + } 43 + ''; 44 + 45 + type = lib.types.submodule { 46 + freeformType = settingsFormat.type; 47 + options = { 48 + ui = lib.mkEnableOption "the OpenBao web UI"; 49 + 50 + listener = lib.mkOption { 51 + type = lib.types.attrsOf ( 52 + lib.types.submodule ( 53 + { config, ... }: 54 + { 55 + freeformType = settingsFormat.type; 56 + options = { 57 + type = lib.mkOption { 58 + type = lib.types.enum [ 59 + "tcp" 60 + "unix" 61 + ]; 62 + description = '' 63 + The listener type to enable. 64 + ''; 65 + }; 66 + address = lib.mkOption { 67 + type = lib.types.str; 68 + default = if config.type == "unix" then "/run/openbao/openbao.sock" else "127.0.0.1:8200"; 69 + defaultText = lib.literalExpression ''if config.services.openbao.settings.listener.<name>.type == "unix" then "/run/openbao/openbao.sock" else "127.0.0.1:8200"''; 70 + description = '' 71 + The TCP address or UNIX socket path to listen on. 72 + ''; 73 + }; 74 + }; 75 + } 76 + ) 77 + ); 78 + description = '' 79 + Configure a listener for responding to requests. 80 + ''; 81 + }; 82 + }; 83 + }; 84 + }; 85 + 86 + extraArgs = lib.mkOption { 87 + type = lib.types.listOf lib.types.str; 88 + default = [ ]; 89 + description = '' 90 + Additional arguments given to OpenBao. 91 + ''; 92 + }; 93 + }; 94 + }; 95 + 96 + config = lib.mkIf cfg.enable { 97 + environment.systemPackages = [ cfg.package ]; 98 + 99 + systemd.services.openbao = { 100 + description = "OpenBao - A tool for managing secrets"; 101 + 102 + wantedBy = [ "multi-user.target" ]; 103 + after = [ "network.target" ]; 104 + 105 + restartIfChanged = false; # do not restart on "nixos-rebuild switch". It would seal the storage and disrupt the clients. 106 + 107 + serviceConfig = { 108 + Type = "notify"; 109 + 110 + ExecStart = lib.escapeShellArgs ( 111 + [ 112 + (lib.getExe cfg.package) 113 + "server" 114 + "-config" 115 + (settingsFormat.generate "openbao.hcl.json" cfg.settings) 116 + ] 117 + ++ cfg.extraArgs 118 + ); 119 + ExecReload = "${lib.getExe' pkgs.coreutils "kill"} -SIGHUP $MAINPID"; 120 + 121 + StateDirectory = "openbao"; 122 + StateDirectoryMode = "0700"; 123 + RuntimeDirectory = "openbao"; 124 + RuntimeDirectoryMode = "0700"; 125 + 126 + CapabilityBoundingSet = ""; 127 + DynamicUser = true; 128 + LimitCORE = 0; 129 + LockPersonality = true; 130 + MemorySwapMax = 0; 131 + MemoryZSwapMax = 0; 132 + PrivateUsers = true; 133 + ProcSubset = "pid"; 134 + ProtectClock = true; 135 + ProtectControlGroups = true; 136 + ProtectHome = true; 137 + ProtectHostname = true; 138 + ProtectKernelLogs = true; 139 + ProtectKernelModules = true; 140 + ProtectKernelTunables = true; 141 + ProtectProc = "invisible"; 142 + Restart = "on-failure"; 143 + RestrictAddressFamilies = [ 144 + "AF_INET" 145 + "AF_INET6" 146 + "AF_UNIX" 147 + ]; 148 + RestrictNamespaces = true; 149 + RestrictRealtime = true; 150 + SystemCallArchitectures = "native"; 151 + SystemCallFilter = [ 152 + "@system-service" 153 + "@resources" 154 + "~@privileged" 155 + ]; 156 + UMask = "0077"; 157 + }; 158 + }; 159 + }; 160 + }
+1
nixos/tests/all-tests.nix
··· 972 972 ollama-rocm = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./ollama-rocm.nix; 973 973 ombi = handleTest ./ombi.nix { }; 974 974 openarena = handleTest ./openarena.nix { }; 975 + openbao = runTest ./openbao.nix; 975 976 openldap = handleTest ./openldap.nix { }; 976 977 opensearch = discoverTests (import ./opensearch.nix); 977 978 openresty-lua = handleTest ./openresty-lua.nix { };
+105
nixos/tests/openbao.nix
··· 1 + { lib, ... }: 2 + let 3 + certs = import ./common/acme/server/snakeoil-certs.nix; 4 + domain = certs.domain; 5 + in 6 + { 7 + name = "openbao"; 8 + 9 + meta.maintainers = with lib.maintainers; [ kranzes ]; 10 + 11 + nodes.machine = 12 + { config, ... }: 13 + { 14 + security.pki.certificateFiles = [ certs.ca.cert ]; 15 + 16 + networking.extraHosts = '' 17 + 127.0.0.1 ${domain} 18 + ''; 19 + 20 + services.openbao = { 21 + enable = true; 22 + 23 + settings = { 24 + ui = true; 25 + 26 + listener = { 27 + default = { 28 + type = "tcp"; 29 + tls_cert_file = certs.${domain}.cert; 30 + tls_key_file = certs.${domain}.key; 31 + }; 32 + 33 + unix = { 34 + type = "unix"; 35 + }; 36 + }; 37 + 38 + cluster_addr = "https://127.0.0.1:8201"; 39 + api_addr = "https://${domain}:8200"; 40 + 41 + storage.raft.path = "/var/lib/openbao"; 42 + }; 43 + }; 44 + 45 + environment.variables = { 46 + BAO_ADDR = config.services.openbao.settings.api_addr; 47 + BAO_FORMAT = "json"; 48 + }; 49 + }; 50 + 51 + testScript = 52 + { nodes, ... }: 53 + '' 54 + import json 55 + 56 + start_all() 57 + 58 + with subtest("Wait for OpenBao to start up"): 59 + machine.wait_for_unit("openbao.service") 60 + machine.wait_for_open_port(8200) 61 + machine.wait_for_open_unix_socket("${nodes.machine.services.openbao.settings.listener.unix.address}") 62 + 63 + with subtest("Check that the web UI is being served"): 64 + machine.succeed("curl -L --fail --show-error --silent $BAO_ADDR | grep '<title>OpenBao</title>'") 65 + 66 + with subtest("Check that OpenBao is not initialized"): 67 + status_output = json.loads(machine.fail("bao status")) 68 + assert not status_output["initialized"] 69 + 70 + with subtest("Initialize OpenBao"): 71 + init_output = json.loads(machine.succeed("bao operator init")) 72 + 73 + with subtest("Check that OpenBao is initialized and sealed"): 74 + status_output = json.loads(machine.fail("bao status")) 75 + assert status_output["initialized"] 76 + assert status_output["sealed"] 77 + 78 + with subtest("Unseal OpenBao"): 79 + for key in init_output["unseal_keys_b64"][:init_output["unseal_threshold"]]: 80 + machine.succeed(f"bao operator unseal {key}") 81 + 82 + with subtest("Check that OpenBao is not sealed"): 83 + status_output = json.loads(machine.succeed("bao status")) 84 + assert not status_output["sealed"] 85 + 86 + with subtest("Login with root token"): 87 + machine.succeed(f"bao login {init_output["root_token"]}") 88 + 89 + with subtest("Enable userpass auth method"): 90 + machine.succeed("bao auth enable userpass") 91 + 92 + with subtest("Create a user in userpass"): 93 + machine.succeed("bao write auth/userpass/users/testuser password=testpassword") 94 + 95 + with subtest("Login to a user from userpass"): 96 + machine.succeed("bao login -method userpass username=testuser password=testpassword") 97 + 98 + with subtest("Write a secret to cubbyhole"): 99 + machine.succeed("bao write cubbyhole/my-secret my-value=s3cr3t") 100 + 101 + with subtest("Read a secret from cubbyhole"): 102 + read_output = json.loads(machine.succeed("bao read cubbyhole/my-secret")) 103 + assert read_output["data"]["my-value"] == "s3cr3t" 104 + ''; 105 + }
+28 -27
pkgs/by-name/op/openbao/package.nix
··· 3 3 fetchFromGitHub, 4 4 buildGoModule, 5 5 go_1_24, 6 - testers, 7 - openbao, 8 6 versionCheckHook, 9 7 nix-update-script, 8 + nixosTests, 9 + callPackage, 10 + stdenvNoCC, 11 + withUi ? true, 12 + withHsm ? stdenvNoCC.hostPlatform.isLinux, 10 13 }: 11 14 12 - buildGoModule.override { go = go_1_24; } rec { 15 + buildGoModule.override { go = go_1_24; } (finalAttrs: { 13 16 pname = "openbao"; 14 - version = "2.2.0"; 17 + version = "2.2.1"; 15 18 16 19 src = fetchFromGitHub { 17 20 owner = "openbao"; 18 21 repo = "openbao"; 19 - tag = "v${version}"; 20 - hash = "sha256-dDMOeAceMaSrF7P4JZ2MKy6zDa10LxCQKkKwu/Q3kOU="; 22 + tag = "v${finalAttrs.version}"; 23 + hash = "sha256-qbLaa7EUQywPRTIgUclTomDDBxzdQnyVAqCGD+iOlpg="; 21 24 }; 22 25 23 - vendorHash = "sha256-zcMc63B/jTUykPfRKvea27xRxjOV+zytaxKOEQAUz1Q="; 26 + vendorHash = "sha256-Upvv3dxS6HIFxR6T+2/dqnFsUtemjOGUaiICgPlepJ8="; 24 27 25 28 proxyVendor = true; 26 29 27 30 subPackages = [ "." ]; 28 31 29 - tags = [ 30 - "openbao" 31 - "bao" 32 - ]; 32 + tags = lib.optional withHsm "hsm" ++ lib.optional withUi "ui"; 33 33 34 34 ldflags = [ 35 35 "-s" 36 36 "-w" 37 - "-X github.com/openbao/openbao/version.GitCommit=${src.rev}" 38 - "-X github.com/openbao/openbao/version.fullVersion=${version}" 37 + "-X github.com/openbao/openbao/version.GitCommit=${finalAttrs.src.rev}" 38 + "-X github.com/openbao/openbao/version.fullVersion=${finalAttrs.version}" 39 + "-X github.com/openbao/openbao/version.buildDate=1970-01-01T00:00:00Z" 39 40 ]; 40 41 42 + postConfigure = lib.optionalString withUi '' 43 + cp -r --no-preserve=mode ${finalAttrs.passthru.ui} http/web_ui 44 + ''; 45 + 41 46 postInstall = '' 42 47 mv $out/bin/openbao $out/bin/bao 43 48 ''; 44 - 45 - # TODO: Enable the NixOS tests after adding OpenBao as a NixOS service in an upcoming PR and 46 - # adding NixOS tests 47 - # 48 - # passthru.tests = { inherit (nixosTests) vault vault-postgresql vault-dev vault-agent; }; 49 - 50 - passthru.tests.version = testers.testVersion { 51 - package = openbao; 52 - command = "HOME=$(mktemp -d) bao --version"; 53 - version = "v${version}"; 54 - }; 55 49 56 50 nativeInstallCheckInputs = [ 57 51 versionCheckHook ··· 61 55 doInstallCheck = true; 62 56 63 57 passthru = { 64 - updateScript = nix-update-script { }; 58 + ui = callPackage ./ui.nix { }; 59 + tests = { inherit (nixosTests) openbao; }; 60 + updateScript = nix-update-script { 61 + extraArgs = [ 62 + "--subpackage" 63 + "ui" 64 + ]; 65 + }; 65 66 }; 66 67 67 68 meta = { 68 69 homepage = "https://www.openbao.org/"; 69 70 description = "Open source, community-driven fork of Vault managed by the Linux Foundation"; 70 - changelog = "https://github.com/openbao/openbao/blob/v${version}/CHANGELOG.md"; 71 + changelog = "https://github.com/openbao/openbao/blob/v${finalAttrs.version}/CHANGELOG.md"; 71 72 license = lib.licenses.mpl20; 72 73 mainProgram = "bao"; 73 74 maintainers = with lib.maintainers; [ brianmay ]; 74 75 }; 75 - } 76 + })
+34
pkgs/by-name/op/openbao/ui.nix
··· 1 + { 2 + stdenvNoCC, 3 + openbao, 4 + yarn-berry_3, 5 + nodejs, 6 + }: 7 + 8 + stdenvNoCC.mkDerivation (finalAttrs: { 9 + pname = openbao.pname + "-ui"; 10 + inherit (openbao) version src; 11 + sourceRoot = "${finalAttrs.src.name}/ui"; 12 + 13 + offlineCache = yarn-berry_3.fetchYarnBerryDeps { 14 + inherit (finalAttrs) src sourceRoot; 15 + hash = "sha256-bQ+ph7CvPtygvCoCMjTMadYLn/ds2ZOGQL29x3hFuLg="; 16 + }; 17 + 18 + nativeBuildInputs = [ 19 + yarn-berry_3.yarnBerryConfigHook 20 + nodejs 21 + yarn-berry_3 22 + ]; 23 + 24 + env.YARN_ENABLE_SCRIPTS = 0; 25 + 26 + postConfigure = '' 27 + substituteInPlace .ember-cli \ 28 + --replace-fail "../http/web_ui" "$out" 29 + ''; 30 + 31 + buildPhase = "yarn run ember build --environment=production"; 32 + 33 + dontInstall = true; 34 + })