Loading nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -1426,6 +1426,7 @@ ./services/security/nginx-sso.nix ./services/security/oauth2-proxy.nix ./services/security/oauth2-proxy-nginx.nix ./services/security/openbao.nix ./services/security/opensnitch.nix ./services/security/paretosecurity.nix ./services/security/pass-secret-service.nix Loading nixos/modules/services/security/openbao.nix 0 → 100644 +160 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: let cfg = config.services.openbao; settingsFormat = pkgs.formats.json { }; in { options = { services.openbao = { enable = lib.mkEnableOption "OpenBao daemon"; package = lib.mkPackageOption pkgs "openbao" { example = "pkgs.openbao.override { withHsm = false; withUi = false; }"; }; settings = lib.mkOption { description = '' Settings of OpenBao. See [documentation](https://openbao.org/docs/configuration) for more details. ''; example = lib.literalExpression '' { ui = true; listener.default = { type = "tcp"; tls_acme_email = config.security.acme.defaults.email; tls_acme_domains = [ "example.com" ]; tls_acme_disable_http_challenge = true; }; cluster_addr = "http://127.0.0.1:8201"; api_addr = "https://example.com"; storage.raft.path = "/var/lib/openbao"; } ''; type = lib.types.submodule { freeformType = settingsFormat.type; options = { ui = lib.mkEnableOption "the OpenBao web UI"; listener = lib.mkOption { type = lib.types.attrsOf ( lib.types.submodule ( { config, ... }: { freeformType = settingsFormat.type; options = { type = lib.mkOption { type = lib.types.enum [ "tcp" "unix" ]; description = '' The listener type to enable. ''; }; address = lib.mkOption { type = lib.types.str; default = if config.type == "unix" then "/run/openbao/openbao.sock" else "127.0.0.1:8200"; defaultText = lib.literalExpression ''if config.services.openbao.settings.listener.<name>.type == "unix" then "/run/openbao/openbao.sock" else "127.0.0.1:8200"''; description = '' The TCP address or UNIX socket path to listen on. ''; }; }; } ) ); description = '' Configure a listener for responding to requests. ''; }; }; }; }; extraArgs = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = '' Additional arguments given to OpenBao. ''; }; }; }; config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package ]; systemd.services.openbao = { description = "OpenBao - A tool for managing secrets"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; restartIfChanged = false; # do not restart on "nixos-rebuild switch". It would seal the storage and disrupt the clients. serviceConfig = { Type = "notify"; ExecStart = lib.escapeShellArgs ( [ (lib.getExe cfg.package) "server" "-config" (settingsFormat.generate "openbao.hcl.json" cfg.settings) ] ++ cfg.extraArgs ); ExecReload = "${lib.getExe' pkgs.coreutils "kill"} -SIGHUP $MAINPID"; StateDirectory = "openbao"; StateDirectoryMode = "0700"; RuntimeDirectory = "openbao"; RuntimeDirectoryMode = "0700"; CapabilityBoundingSet = ""; DynamicUser = true; LimitCORE = 0; LockPersonality = true; MemorySwapMax = 0; MemoryZSwapMax = 0; PrivateUsers = true; ProcSubset = "pid"; ProtectClock = true; ProtectControlGroups = true; ProtectHome = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; Restart = "on-failure"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; RestrictNamespaces = true; RestrictRealtime = true; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" "@resources" "~@privileged" ]; UMask = "0077"; }; }; }; } nixos/tests/all-tests.nix +1 −0 Original line number Diff line number Diff line Loading @@ -972,6 +972,7 @@ in ollama-rocm = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./ollama-rocm.nix; ombi = handleTest ./ombi.nix { }; openarena = handleTest ./openarena.nix { }; openbao = runTest ./openbao.nix; openldap = handleTest ./openldap.nix { }; opensearch = discoverTests (import ./opensearch.nix); openresty-lua = handleTest ./openresty-lua.nix { }; Loading nixos/tests/openbao.nix 0 → 100644 +105 −0 Original line number Diff line number Diff line { lib, ... }: let certs = import ./common/acme/server/snakeoil-certs.nix; domain = certs.domain; in { name = "openbao"; meta.maintainers = with lib.maintainers; [ kranzes ]; nodes.machine = { config, ... }: { security.pki.certificateFiles = [ certs.ca.cert ]; networking.extraHosts = '' 127.0.0.1 ${domain} ''; services.openbao = { enable = true; settings = { ui = true; listener = { default = { type = "tcp"; tls_cert_file = certs.${domain}.cert; tls_key_file = certs.${domain}.key; }; unix = { type = "unix"; }; }; cluster_addr = "https://127.0.0.1:8201"; api_addr = "https://${domain}:8200"; storage.raft.path = "/var/lib/openbao"; }; }; environment.variables = { BAO_ADDR = config.services.openbao.settings.api_addr; BAO_FORMAT = "json"; }; }; testScript = { nodes, ... }: '' import json start_all() with subtest("Wait for OpenBao to start up"): machine.wait_for_unit("openbao.service") machine.wait_for_open_port(8200) machine.wait_for_open_unix_socket("${nodes.machine.services.openbao.settings.listener.unix.address}") with subtest("Check that the web UI is being served"): machine.succeed("curl -L --fail --show-error --silent $BAO_ADDR | grep '<title>OpenBao</title>'") with subtest("Check that OpenBao is not initialized"): status_output = json.loads(machine.fail("bao status")) assert not status_output["initialized"] with subtest("Initialize OpenBao"): init_output = json.loads(machine.succeed("bao operator init")) with subtest("Check that OpenBao is initialized and sealed"): status_output = json.loads(machine.fail("bao status")) assert status_output["initialized"] assert status_output["sealed"] with subtest("Unseal OpenBao"): for key in init_output["unseal_keys_b64"][:init_output["unseal_threshold"]]: machine.succeed(f"bao operator unseal {key}") with subtest("Check that OpenBao is not sealed"): status_output = json.loads(machine.succeed("bao status")) assert not status_output["sealed"] with subtest("Login with root token"): machine.succeed(f"bao login {init_output["root_token"]}") with subtest("Enable userpass auth method"): machine.succeed("bao auth enable userpass") with subtest("Create a user in userpass"): machine.succeed("bao write auth/userpass/users/testuser password=testpassword") with subtest("Login to a user from userpass"): machine.succeed("bao login -method userpass username=testuser password=testpassword") with subtest("Write a secret to cubbyhole"): machine.succeed("bao write cubbyhole/my-secret my-value=s3cr3t") with subtest("Read a secret from cubbyhole"): read_output = json.loads(machine.succeed("bao read cubbyhole/my-secret")) assert read_output["data"]["my-value"] == "s3cr3t" ''; } pkgs/by-name/op/openbao/package.nix +28 −27 Original line number Diff line number Diff line Loading @@ -3,56 +3,50 @@ fetchFromGitHub, buildGoModule, go_1_24, testers, openbao, versionCheckHook, nix-update-script, nixosTests, callPackage, stdenvNoCC, withUi ? true, withHsm ? stdenvNoCC.hostPlatform.isLinux, }: buildGoModule.override { go = go_1_24; } rec { buildGoModule.override { go = go_1_24; } (finalAttrs: { pname = "openbao"; version = "2.2.0"; version = "2.2.1"; src = fetchFromGitHub { owner = "openbao"; repo = "openbao"; tag = "v${version}"; hash = "sha256-dDMOeAceMaSrF7P4JZ2MKy6zDa10LxCQKkKwu/Q3kOU="; tag = "v${finalAttrs.version}"; hash = "sha256-qbLaa7EUQywPRTIgUclTomDDBxzdQnyVAqCGD+iOlpg="; }; vendorHash = "sha256-zcMc63B/jTUykPfRKvea27xRxjOV+zytaxKOEQAUz1Q="; vendorHash = "sha256-Upvv3dxS6HIFxR6T+2/dqnFsUtemjOGUaiICgPlepJ8="; proxyVendor = true; subPackages = [ "." ]; tags = [ "openbao" "bao" ]; tags = lib.optional withHsm "hsm" ++ lib.optional withUi "ui"; ldflags = [ "-s" "-w" "-X github.com/openbao/openbao/version.GitCommit=${src.rev}" "-X github.com/openbao/openbao/version.fullVersion=${version}" "-X github.com/openbao/openbao/version.GitCommit=${finalAttrs.src.rev}" "-X github.com/openbao/openbao/version.fullVersion=${finalAttrs.version}" "-X github.com/openbao/openbao/version.buildDate=1970-01-01T00:00:00Z" ]; postConfigure = lib.optionalString withUi '' cp -r --no-preserve=mode ${finalAttrs.passthru.ui} http/web_ui ''; postInstall = '' mv $out/bin/openbao $out/bin/bao ''; # TODO: Enable the NixOS tests after adding OpenBao as a NixOS service in an upcoming PR and # adding NixOS tests # # passthru.tests = { inherit (nixosTests) vault vault-postgresql vault-dev vault-agent; }; passthru.tests.version = testers.testVersion { package = openbao; command = "HOME=$(mktemp -d) bao --version"; version = "v${version}"; }; nativeInstallCheckInputs = [ versionCheckHook ]; Loading @@ -61,15 +55,22 @@ buildGoModule.override { go = go_1_24; } rec { doInstallCheck = true; passthru = { updateScript = nix-update-script { }; ui = callPackage ./ui.nix { }; tests = { inherit (nixosTests) openbao; }; updateScript = nix-update-script { extraArgs = [ "--subpackage" "ui" ]; }; }; meta = { homepage = "https://www.openbao.org/"; description = "Open source, community-driven fork of Vault managed by the Linux Foundation"; changelog = "https://github.com/openbao/openbao/blob/v${version}/CHANGELOG.md"; changelog = "https://github.com/openbao/openbao/blob/v${finalAttrs.version}/CHANGELOG.md"; license = lib.licenses.mpl20; mainProgram = "bao"; maintainers = with lib.maintainers; [ brianmay ]; }; } }) Loading
nixos/modules/module-list.nix +1 −0 Original line number Diff line number Diff line Loading @@ -1426,6 +1426,7 @@ ./services/security/nginx-sso.nix ./services/security/oauth2-proxy.nix ./services/security/oauth2-proxy-nginx.nix ./services/security/openbao.nix ./services/security/opensnitch.nix ./services/security/paretosecurity.nix ./services/security/pass-secret-service.nix Loading
nixos/modules/services/security/openbao.nix 0 → 100644 +160 −0 Original line number Diff line number Diff line { config, lib, pkgs, ... }: let cfg = config.services.openbao; settingsFormat = pkgs.formats.json { }; in { options = { services.openbao = { enable = lib.mkEnableOption "OpenBao daemon"; package = lib.mkPackageOption pkgs "openbao" { example = "pkgs.openbao.override { withHsm = false; withUi = false; }"; }; settings = lib.mkOption { description = '' Settings of OpenBao. See [documentation](https://openbao.org/docs/configuration) for more details. ''; example = lib.literalExpression '' { ui = true; listener.default = { type = "tcp"; tls_acme_email = config.security.acme.defaults.email; tls_acme_domains = [ "example.com" ]; tls_acme_disable_http_challenge = true; }; cluster_addr = "http://127.0.0.1:8201"; api_addr = "https://example.com"; storage.raft.path = "/var/lib/openbao"; } ''; type = lib.types.submodule { freeformType = settingsFormat.type; options = { ui = lib.mkEnableOption "the OpenBao web UI"; listener = lib.mkOption { type = lib.types.attrsOf ( lib.types.submodule ( { config, ... }: { freeformType = settingsFormat.type; options = { type = lib.mkOption { type = lib.types.enum [ "tcp" "unix" ]; description = '' The listener type to enable. ''; }; address = lib.mkOption { type = lib.types.str; default = if config.type == "unix" then "/run/openbao/openbao.sock" else "127.0.0.1:8200"; defaultText = lib.literalExpression ''if config.services.openbao.settings.listener.<name>.type == "unix" then "/run/openbao/openbao.sock" else "127.0.0.1:8200"''; description = '' The TCP address or UNIX socket path to listen on. ''; }; }; } ) ); description = '' Configure a listener for responding to requests. ''; }; }; }; }; extraArgs = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; description = '' Additional arguments given to OpenBao. ''; }; }; }; config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package ]; systemd.services.openbao = { description = "OpenBao - A tool for managing secrets"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; restartIfChanged = false; # do not restart on "nixos-rebuild switch". It would seal the storage and disrupt the clients. serviceConfig = { Type = "notify"; ExecStart = lib.escapeShellArgs ( [ (lib.getExe cfg.package) "server" "-config" (settingsFormat.generate "openbao.hcl.json" cfg.settings) ] ++ cfg.extraArgs ); ExecReload = "${lib.getExe' pkgs.coreutils "kill"} -SIGHUP $MAINPID"; StateDirectory = "openbao"; StateDirectoryMode = "0700"; RuntimeDirectory = "openbao"; RuntimeDirectoryMode = "0700"; CapabilityBoundingSet = ""; DynamicUser = true; LimitCORE = 0; LockPersonality = true; MemorySwapMax = 0; MemoryZSwapMax = 0; PrivateUsers = true; ProcSubset = "pid"; ProtectClock = true; ProtectControlGroups = true; ProtectHome = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; Restart = "on-failure"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; RestrictNamespaces = true; RestrictRealtime = true; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service" "@resources" "~@privileged" ]; UMask = "0077"; }; }; }; }
nixos/tests/all-tests.nix +1 −0 Original line number Diff line number Diff line Loading @@ -972,6 +972,7 @@ in ollama-rocm = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./ollama-rocm.nix; ombi = handleTest ./ombi.nix { }; openarena = handleTest ./openarena.nix { }; openbao = runTest ./openbao.nix; openldap = handleTest ./openldap.nix { }; opensearch = discoverTests (import ./opensearch.nix); openresty-lua = handleTest ./openresty-lua.nix { }; Loading
nixos/tests/openbao.nix 0 → 100644 +105 −0 Original line number Diff line number Diff line { lib, ... }: let certs = import ./common/acme/server/snakeoil-certs.nix; domain = certs.domain; in { name = "openbao"; meta.maintainers = with lib.maintainers; [ kranzes ]; nodes.machine = { config, ... }: { security.pki.certificateFiles = [ certs.ca.cert ]; networking.extraHosts = '' 127.0.0.1 ${domain} ''; services.openbao = { enable = true; settings = { ui = true; listener = { default = { type = "tcp"; tls_cert_file = certs.${domain}.cert; tls_key_file = certs.${domain}.key; }; unix = { type = "unix"; }; }; cluster_addr = "https://127.0.0.1:8201"; api_addr = "https://${domain}:8200"; storage.raft.path = "/var/lib/openbao"; }; }; environment.variables = { BAO_ADDR = config.services.openbao.settings.api_addr; BAO_FORMAT = "json"; }; }; testScript = { nodes, ... }: '' import json start_all() with subtest("Wait for OpenBao to start up"): machine.wait_for_unit("openbao.service") machine.wait_for_open_port(8200) machine.wait_for_open_unix_socket("${nodes.machine.services.openbao.settings.listener.unix.address}") with subtest("Check that the web UI is being served"): machine.succeed("curl -L --fail --show-error --silent $BAO_ADDR | grep '<title>OpenBao</title>'") with subtest("Check that OpenBao is not initialized"): status_output = json.loads(machine.fail("bao status")) assert not status_output["initialized"] with subtest("Initialize OpenBao"): init_output = json.loads(machine.succeed("bao operator init")) with subtest("Check that OpenBao is initialized and sealed"): status_output = json.loads(machine.fail("bao status")) assert status_output["initialized"] assert status_output["sealed"] with subtest("Unseal OpenBao"): for key in init_output["unseal_keys_b64"][:init_output["unseal_threshold"]]: machine.succeed(f"bao operator unseal {key}") with subtest("Check that OpenBao is not sealed"): status_output = json.loads(machine.succeed("bao status")) assert not status_output["sealed"] with subtest("Login with root token"): machine.succeed(f"bao login {init_output["root_token"]}") with subtest("Enable userpass auth method"): machine.succeed("bao auth enable userpass") with subtest("Create a user in userpass"): machine.succeed("bao write auth/userpass/users/testuser password=testpassword") with subtest("Login to a user from userpass"): machine.succeed("bao login -method userpass username=testuser password=testpassword") with subtest("Write a secret to cubbyhole"): machine.succeed("bao write cubbyhole/my-secret my-value=s3cr3t") with subtest("Read a secret from cubbyhole"): read_output = json.loads(machine.succeed("bao read cubbyhole/my-secret")) assert read_output["data"]["my-value"] == "s3cr3t" ''; }
pkgs/by-name/op/openbao/package.nix +28 −27 Original line number Diff line number Diff line Loading @@ -3,56 +3,50 @@ fetchFromGitHub, buildGoModule, go_1_24, testers, openbao, versionCheckHook, nix-update-script, nixosTests, callPackage, stdenvNoCC, withUi ? true, withHsm ? stdenvNoCC.hostPlatform.isLinux, }: buildGoModule.override { go = go_1_24; } rec { buildGoModule.override { go = go_1_24; } (finalAttrs: { pname = "openbao"; version = "2.2.0"; version = "2.2.1"; src = fetchFromGitHub { owner = "openbao"; repo = "openbao"; tag = "v${version}"; hash = "sha256-dDMOeAceMaSrF7P4JZ2MKy6zDa10LxCQKkKwu/Q3kOU="; tag = "v${finalAttrs.version}"; hash = "sha256-qbLaa7EUQywPRTIgUclTomDDBxzdQnyVAqCGD+iOlpg="; }; vendorHash = "sha256-zcMc63B/jTUykPfRKvea27xRxjOV+zytaxKOEQAUz1Q="; vendorHash = "sha256-Upvv3dxS6HIFxR6T+2/dqnFsUtemjOGUaiICgPlepJ8="; proxyVendor = true; subPackages = [ "." ]; tags = [ "openbao" "bao" ]; tags = lib.optional withHsm "hsm" ++ lib.optional withUi "ui"; ldflags = [ "-s" "-w" "-X github.com/openbao/openbao/version.GitCommit=${src.rev}" "-X github.com/openbao/openbao/version.fullVersion=${version}" "-X github.com/openbao/openbao/version.GitCommit=${finalAttrs.src.rev}" "-X github.com/openbao/openbao/version.fullVersion=${finalAttrs.version}" "-X github.com/openbao/openbao/version.buildDate=1970-01-01T00:00:00Z" ]; postConfigure = lib.optionalString withUi '' cp -r --no-preserve=mode ${finalAttrs.passthru.ui} http/web_ui ''; postInstall = '' mv $out/bin/openbao $out/bin/bao ''; # TODO: Enable the NixOS tests after adding OpenBao as a NixOS service in an upcoming PR and # adding NixOS tests # # passthru.tests = { inherit (nixosTests) vault vault-postgresql vault-dev vault-agent; }; passthru.tests.version = testers.testVersion { package = openbao; command = "HOME=$(mktemp -d) bao --version"; version = "v${version}"; }; nativeInstallCheckInputs = [ versionCheckHook ]; Loading @@ -61,15 +55,22 @@ buildGoModule.override { go = go_1_24; } rec { doInstallCheck = true; passthru = { updateScript = nix-update-script { }; ui = callPackage ./ui.nix { }; tests = { inherit (nixosTests) openbao; }; updateScript = nix-update-script { extraArgs = [ "--subpackage" "ui" ]; }; }; meta = { homepage = "https://www.openbao.org/"; description = "Open source, community-driven fork of Vault managed by the Linux Foundation"; changelog = "https://github.com/openbao/openbao/blob/v${version}/CHANGELOG.md"; changelog = "https://github.com/openbao/openbao/blob/v${finalAttrs.version}/CHANGELOG.md"; license = lib.licenses.mpl20; mainProgram = "bao"; maintainers = with lib.maintainers; [ brianmay ]; }; } })