Configure security settings

Configure these security settings to ensure your Puppet Enterprise (PE) environment is secure.

Configure cipher suites

Regulatory compliance or other security requirements might require you to change the cipher suites your SSL-enabled PE services use to communicate with other PE components.

Before you begin: Make sure you're using Compatible ciphers.

To add or remove cipher suites for different service types, use Hiera to modify the following parameters:

List IANA-formatted ciphers for all PE Java-based services, which includes PuppetDB, Puppet Server, console services, and the orchestrator.
Format: Array of strings
- 'TLS_AES_256_GCM_SHA384'
- 'TLS_AES_128_GCM_SHA256'
List OpenSSL-formatted ciphers for all PE non-Java services, which includes Bolt Server, ACE Server, and PostgreSQL.
Format: Array of strings
List OpenSSL-formatted ciphers for NGINX. These ciphers are accepted by the PE console in the browser.
Format: Array of strings
- 'TLS_CHACHA20_POLY1305_SHA256'

Configure SSL protocols

You can change what SSL protocols your Puppet Enterprise (PE) infrastructure uses.

Where to configure
In Hiera data files.
In the PE console on the PE Infrastructure node group's Configuration data tab.
Array of strings representing SSL protocols.
This declaration enables TSLv1.3 and TSLv1.2:
puppet_enterprise::master::puppetserver::ssl_protocols: ["TLSv1.3", "TLSv1.2"]
["TLSv1.3", "TLSv1.2"]
Note: To comply with security regulations, only versions 1.2 and 1.3 of the Transport Layer Security (TLS) protocol are enabled. If necessary, you can manually enable TLSv1 and TSLv1.1.

Configure RBAC and token-based authentication settings

You can configure RBAC and token-based authentication settings, such as setting the number of failed attempts a user has before they are locked out of the console or the amount of time tokens are valid.

RBAC and token authentication settings can be changed in the PE Infrastructure node group in the Puppet Enterprise (PE) console or in Hiera data. Settings include:
An integer specifying how many failed login attempts are allowed on an account before the account is revoked.
Default: 10
An integer representing the number of hours that password reset tokens are valid.
An administrator generates these token for users to reset their passwords.
Default: 24
An integer representing, in minutes, how long a user's session can last.
The session length is the same for node classification, RBAC, and the console.
Default: 60
A string representing the default authentication lifetime for a token.
The value is formatted as string consisting of a number followed by a suffix representing a unit of time: y (years), d (days), h (hours), m (minutes), or s (seconds).
Important: This value cannot exceed the rbac_token_maximum_lifetime.
Default: "1h" (one hour)
A string representing the maximum allowable lifetime for all tokens.
The value is formatted as a string consisting of a number followed by a suffix representing a unit of time: y (years), d (days), h (hours), m (minutes), or s (seconds).
Default: 10y (10 years)
An integer specifying, in minutes, how often the application checks for idle user accounts.
Default: 60 minutes
Important: The rbac_account_expiry_check_minutes parameter is ignored if you do not also specify the rbac_account_expiry_days parameter.
An integer specifying, in days, the duration before an inactive user account expires.
The default value is undefined. To activate this feature, specify a positive integer of 1 or greater.
When non-superusers don't log into the console during the specified period, their user status changes to revoked. This also applies to new accounts – The inactivity timer starts once the account is created.
An integer specifying, in seconds, the interval at which LDAP group membership associations are synchronized.
The default value is 1800 (30 minutes).
This synchronization refreshes group membership for every LDAP user in the system, regardless of the last time the user logged in. If a user is no longer present in LDAP or has no group bindings, then all user-group associations are removed from the user and all of the user's known tokens are revoked; however, the user object itself is not removed. If a user is present in LDAP and has group bindings, this synchronization updates the user's group membership, user name, and descriptions (if this data had changed).
To disable automatic synchronization, set the value to 0 or a negative integer. When disabled, user names, descriptions, and group membership only refresh when users log in.
When enabled, various entries are recorded to console-services.log that indicate whether the service is enabled and when each synchronization event has completed. If you enabled SAML after LDAP, these logs can show tokens being revoked in associated with past LDAP users if those users haven't logged in through SAML.

RBAC database configuration

Credential information for the RBAC service is stored in a PostgreSQL database. Configuration information for this database is in the rbac-database section of the config file.

For example:
rbac-database: {
  classname: org.postgresql.Driver
  subprotocol: postgresql
  subname: "//<PATH_TO_HOST>:5432/perbac"
  user: <USERNAME>
  password: <PASSWORD>
It contains these parameters:
Used by the RBAC service for connecting to the database.
The value must be org.postgresql.Driver.
Used by the RBAC service for connecting to the database.
The value must always be postgresql.
The JDBC connection path used by the RBAC service for connecting to the database.
The value is a string-formatted URI path consisting of the hostname and configured port for the PostgreSQL database along with perbac, such as
perbac is the database the RBAC service uses to store credentials.
This is the username the RBAC service uses to connect to the PostgreSQL database.
This is the password the RBAC service uses to connect to the PostgreSQL database.

Configure the password algorithm

Puppet Enterprise (PE) uses SHA-256 as a default password algorithm. You can use Hiera or the PE console to change the algorithm to argon2id by editing or adding password algorithm parameters.

Before you begin: Before changing your password algorithm to argon2id, review the Argon2 specifications on
Restriction: If you have FIPS 140-2 enabled PE, use the default SHA-256 algorithm, because Argon2id isn’t available for FIPS-enabled systems.
A string, either "SHA-256" or "ARGON2ID".
Always required.
Default: "SHA-256"
An integer representing the desired hash output size in bytes.
Required for argon2id.
Default: 128 bytes
An integer representing the number of parallel computations that can be performed at once.
Required for argon2id.
Default: Twice the number of cores in your system.
An integer representing the amount of memory, in KB, the algorithm consumes when running.
Required for argon2id.
No default value. We recommend initially setting this to 25% of your CPU memory.
An integer representing the number of times a password is hashed before it’s stored.
Always required, and we recommend updating this value when switching from SHA-256 to argon2id. The minimum recommended value for argon2id is 3 iterations.
Default: 500000 iterations.
An integer representing the size, in bytes, of each generated salt.
Default: 128 bytes

Add a custom HSTS header to NGINX

An HTTP Strict Transport Security (HSTS) response header is a security header that blocks access to non-HTTPS content. This prevents the browser from being exploited by man-in-the-middle attacks.

You can't use self-signed certificates with HSTS headers. Therefore, if you want to enable an HSTS header, you must first add a custom certificate with a trusted CA to your Puppet Enterprise (PE) console, and then use a custom NGINX module to define and manage the header content.
  1. Add a custom certificate as explained in Use a custom SSL certificate for the console.
  2. Write a custom NGINX module for managing the headers that includes a headers.conf file.
    Tip: Use the Beginner's guide to writing modules in the Puppet documentation to learn how to write custom modules.
    For example, assume your custom module is called nginxcustom. The custom module's location is:
    And it has the following structure:
    ├── files 
    │       └── headers.conf 
    └── manifests 
    	└── init.pp
  3. Define the HSTS response header content in a header.conf file, such as:
    # cat files/headers.conf
    #Custom headers 
    add_header X-Frame-Options SAMEORIGIN always; 
    add_header X-Content-Type-Options nosniff; 
    add_header X-XSS-Protection '1; mode=block'; 
    add_header Strict-Transport-Security 'max-age=63072000; includeSubDomains; preload;';
  4. In manifests/init.pp, create a file resource that points to the custom module that manages your headers.conf file.
    For example, this file resource points to the nginxcustom module:
    # cat manifests/init.pp
     #File resource to create headers.conf
     class nginxcustom {
        file { '/etc/puppetlabs/nginx/headers.conf':
          ensure => file,
          group => 'root',
          owner => 'root',
          mode => '0644',
          source =>'puppet:///modules/nginxcustom/headers.conf',
  5. In manifests/init.pp, use pe_nginx::directive to include the headers.conf file in the proxy.conf configuration file. This allows the headers to appear in the NGINX configuration in PE. For example:
    #Nginx directive to add include statement 
    pe_nginx::directive { 'include custom headers': 
    directive_ensure => 'present', 
    target => '/etc/puppetlabs/nginx/conf.d/proxy.conf', 
    directive_name => 'include', 
    value => 'headers.conf', 
    server_context => $::fqdn, } 
  6. Run Puppet: puppet agent -t