Hello,

This is a very good topic. It's not so elegant, but I think you can cover your
need today with the @ macro in the configuration file.

You can execute a command that will generate the password (reading from a file
for example, or doing some query in a database), or read a file.

If you want to just read from a file:

Client {
 Name = myclient-fd
 @/opt/bacula/etc/myclient.password
 Address = myclient.lan
 File Retention = 5 years
 Job Retention = 5 years
 ..
}

and in /opt/bacula/etc/myclient.password
you have

# cat /opt/bacula/etc/myclient.password
Password = "this is a secret"

To generate the configuration on the fly with a script, you can use @|
and the path to a program and arguments.

I'm not opposed to have that kind of mechanism built-in with a nicer syntax,
and it's good to discuss this point. I would like for example to be able to use
a password manager as well.

Best Regards,
Eric

On 6/25/25 20:49, Clinton Bunch wrote:
Hello Bacula Developers and Community,

I'd like to initiate a discussion around enhancing how Bacula manages sensitive information like passwords and potentially TLS key passphrases, moving them out of the main configuration files. This aims to improve security, simplify secret rotation, and make Bacula configurations more friendly for version control and modern deployment practices (e.g., with Ansible, Puppet, systemd). Importantly, these proposed enhancements would be entirely optional, ensuring no breakage for existing configurations.

Currently, passwords are often embedded directly in bacula-*.conffiles. This has several drawbacks:

  *

    Exposes secrets if the main config files are inadvertently shared or
    checked into version control without protection.

  *

    Makes secret rotation more error-prone as it requires editing the
    main config.

  *

    Complicates management with configuration automation tools that
    might handle secrets separately.

I propose a few layered approaches to address this, ranging from simpler to more comprehensive:

*1. The file:Directive*

Many users might want to separate files for secrets and pointing to them with restrictive permissions, which is good practice. A Password = "file:/path/to/ secret"directive that simply reads the first line of a file (stripping any trailing newline) would be a foundational improvement.

  *

    *Advantages*:

      o

        Allows separation of secrets from main configuration.

      o

        Easier secret rotation (update file, reload Bacula).

      o

        Configuration files become safer for version control (secret
        files are gitignored/managed separately).

      o

        Aligns well with configuration management tools (e.g., Ansible
        can deploy the main config and then deploy the secret file with
        strict permissions and content from a vault).

*2. The dynfile:Directive (Dynamic/Deferred File Loading)*

Building on file:, the dynfile:prefix would address scenarios where the secret file is provisioned at service startup and might not exist when a configuration check (bacula-* -t) is run. This is particularly relevant for integration with systemd-credentials.

  *

    *Syntax*: Password = "dynfile:/path/to/runtime_secret_file"

  *

    *Key Behavior*:

      o

        During a configuration test (bacula-* -t), if a dynfile:path
        does not exist, Bacula should issue a warning or informational
        message but *not fail the configuration check*. The validity of
        the rest of the configuration can still be assessed.

      o

        At actual runtime, if the dynfile:path doesn't exist when the
        secret is needed, it would be a fatal error.

  *

    *Advantages*:

      o

        All benefits of file:.

      o

        Crucially enables seamless integration with tools like
        systemd-credentials(e.g., LoadCredential=), which make secrets
        available only after the service unit starts processing but
        before the main daemon fully initializes.

      o

        Useful for any custom startup script that generates/places a
        temporary secret file.

*3. The syscred:Directive (Direct systemd-credentials Integration)*

For a more streamlined systemd integration, a dedicated prefix could simplify configuration since the path used by systemd for $CREDENTIALS_DIRECTORYis not guaranteed to remain the same between systems or systemd versions.While there might be a natural reluctance to add code specific to one OS's init system/ credential manager, the prevalence of systemd on Linux platforms and the relative ease of implementing this specific integration could offer a significant "bang for the buck" for a large portion of the user base.

  *

    *Syntax*: Password = "syscred:credential_name"(e.g.,
    syscred:bacula_db_password)

  *

    *Behavior*:

      o

        Bacula reads the $CREDENTIALS_DIRECTORYenvironment variable (set
        by systemd).

      o

        It constructs the full path: $CREDENTIALS_DIRECTORY/credential_name.

      o

        It attempts to read the secret from this path.

      o

        It inherits the "don't fail early" logic from dynfile:for
        configuration checks (if $CREDENTIALS_DIRECTORYisn't set or the
        path doesn't yet exist during -t).

  *

    *Advantages*:

      o

        Simplifies configuration for users on systemd: they only need
        the credential name, not the full runtime path.

      o

        More robust as it adapts to the actual path provided by systemd
        via $CREDENTIALS_DIRECTORY.

      o

        Represents a relatively "simple win" for a large and growing
        portion of the Linux user base, offering a clean, secure, and
        modern way to handle secrets.

      o

        Implementation could leverage the underlying logic developed for
        dynfile:, making it a comparatively straightforward addition.

*Applicability to TLS Keys/Passphrases:*

These file:, dynfile:, and syscred:mechanisms could also be extended to directives like a new TLS Key Passphraseif Bacula were to support encrypted TLS private keys (leveraging the linked OpenSSL library which can handle decryption given a passphrase). This would be a significant security hardening step for TLS keys. TLS Key = "dynfile:/path/to/key_provided_by_systemd"is also an option if systemd provides the decrypted key directly.

*4. The credstore:name:secret_identifierDirective (External Credential Store Helper)*

For maximum flexibility and integration with various secret managers (Vault, AWS Secrets Manager, Azure Key Vault, etc.) and platforms:

  *

    *Syntax*:

      *

        In resource: Password =
        "credstore:myvault:database/production/db_password"

      *

        New Stanza:

        |Credstore { Name = "myvault" Exec =
        "/usr/local/bin/bacula-secret-helper --store vault --secret %s"
        # Or: Exec = "/usr/local/bin/fetch-from-aws --secret %s" Timeout
        = 5 # Optional timeout for the helper }|


   *
   *

    *Behavior*:

      o

        Bacula forks and executes the specified Execcommand,
        substituting %s(or other placeholders) with the secret_identifier.

      o

        The helper script/program is responsible for fetching the secret
        from the external store and printing it to its standard output.

      o

        Bacula reads the secret from the helper's stdout.

  *

    *Advantages*:

      o

        Extremely flexible: supports any secret manager via custom
        helper scripts.

      o

        Platform-agnostic core mechanism (exec).

      o

        Aligns with how many other enterprise tools manage externalized
        secrets.

  *

    *Considerations*:

      o

        Significantly more involved to implement in Bacula (process
        management, IPC, timeout handling, error checking from helper,
        argument substitution).

      o

        Potential performance implications if secrets are fetched very
        frequently (though caching within Bacula could mitigate this).

      o

        Careful design needed for config check mode (e.g., should
        helpers be executed?).

*Discussion Points:*

  *

    Is there general interest in these types of enhancements,
    understanding they would be optional additions?

  *

  *

    Would the proposed file:directive be a welcome foundational feature?

  *

    Following that, would dynfile:(with its specific config-check
    behavior) be a good next step?

  *

    Given its potential ease of implementation and wide user base on
    systemd, is syscred:a desirable simplification, despite being
    OS-specific?

  *

    Is the more comprehensive credstore:exec:model something the
    community sees a long-term need for, despite the implementation effort?

  *

    Are there other approaches or considerations I might have missed?

I believe even the simpler dynfile:and syscred:options would offer substantial benefits to many Bacula users by improving security and manageability without impacting existing setups. The credstore:approach provides a path for even more advanced integrations.

Looking forward to your thoughts and feedback.

Thanks,

Clinton Bunch



_______________________________________________
Bacula-devel mailing list
Bacula-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-devel



_______________________________________________
Bacula-devel mailing list
Bacula-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-devel

Reply via email to