Working with Passwords and other sensitive data with exec

Sometimes we need to set a password using the exec type, and the password must be passed as an argument.

This is problematic, because we’d rather not have the password logged in the debug logs.

Solution: Place the password in an environment variable.

For example, to set the firmware password on Mac hardware:

class osx-nvram {
  Exec { path => "/usr/sbin:/sbin:/usr/bin:/bin" }
  # Password is "m"
  exec { "nvram security-password":
    env => "SECRET=%c7", 
    command => "nvram security-password=\${SECRET}",
    unless => "nvram security-password | awk '{print \$2}' | grep -q \${SECRET}"
  }
  exec { "nvram security-mode":
    command => "nvram security-mode=command",
    unless => "nvram security-mode | awk '{print \$2}' | grep -q command"
  }
}

Using this hackery, we only see this in the debug logs:

...
debug: //default/managed-host/osx-nvram/Exec[nvram security-password]: \
  Executing check 'nvram security-password | awk '{print $2}' | grep -q ${SECRET}'
debug: Executing 'nvram security-password | awk '{print $2}' | grep -q ${SECRET}'
...
debug: //default/managed-host/osx-nvram/Exec[nvram security-password]: \
  Executing 'nvram security-password=${SECRET}'
debug: Executing 'nvram security-password=${SECRET}'
...

Alternative: Using a subshell.

Alternatively, you could place the password in file, manage the file object and ensure it’s locked down correctly, then use a sub-shell to get it into the command line.

For example:

class osx-nvram {
  Exec { path => "/usr/sbin:/sbin:/usr/bin:/bin" }
  exec { "nvram security-password":
    command => "nvram security-password=\$(cat /var/secure/password.txt)",
    unless => "nvram security-password | awk '{print \$2}' | grep -q \$(cat /var/secure/efi_password.txt)",
    require => File["/var/secure/efi_password.txt"]
  }
  exec { "nvram security-mode":
    command => "nvram security-mode=command",
    unless => "nvram security-mode | awk '{print \$2}' | grep -q command"
  }
}