Defined Type: secrets::file

Defined in:
manifests/file.pp

Summary

Manages a file with sensitive content, optional POSIX ACLs, and SELinux context attributes.

Overview

The namevar is a logical descriptor (e.g. ‘krb5 keytab for host foo’). Set $path explicitly when the title is descriptive rather than a file path. Defaults to $title when $title is an absolute path. Will always produce a File resource

Examples:

Descriptive title with explicit path

secrets::file { 'krb5 keytab for host foo':
  path     => '/etc/krb5.keytab',
  content  => lookup('secrets::krb5_keytab'),
  owner    => 'root',
  group    => 'root',
  mode     => '0400',
  posix_acl => {
    action     => 'set',
    permission => ['group:wheel:r--'],
  },
  seluser  => 'system_u',
  selrole  => 'object_r',
  seltype  => 'krb5_keytab_t',
  selrange => 's0',
}

Path as title (shorthand)

secrets::file { '/etc/krb5.keytab':
  content => lookup('secrets::krb5_keytab'),
}

Parameters:

  • content (Variant[String, Sensitive[String]])

    File content. Accepts String or Sensitive. Always stored and written as Sensitive to prevent exposure in logs and reports. When sourced from Hiera, declare the key as Sensitive in lookup_options.

  • path (Optional[Stdlib::Absolutepath]) (defaults to: undef)

    Absolute path of the target file. Defaults to $title when $title is a valid absolute path; must be set explicitly otherwise.

  • owner (Variant[String,Integer]) (defaults to: 'root')

    Passed directly to the ‘file` resource

  • group (Variant[String,Integer]) (defaults to: 'root')

    Passed directly to the ‘file` resource

  • mode (Optional[Pattern[/^[0-7]{4}$/]]) (defaults to: '0400')

    Passed directly to the ‘file` resource

  • seluser (Optional[String[1]]) (defaults to: undef)

    Passed directly to the ‘file` resource

  • selrole (Optional[String[1]]) (defaults to: undef)

    Passed directly to the ‘file` resource

  • seltype (Optional[String[1]]) (defaults to: undef)

    Passed directly to the ‘file` resource

  • selrange (Optional[String[1]]) (defaults to: undef)

    Passed directly to the ‘file` resource

  • selinux_ignore_defaults (Boolean) (defaults to: false)

    Passed directly to the ‘file` resource

  • notify_services (Array) (defaults to: [])

    Service titles to try and notify if this changes

  • posix_acl (Hash) (defaults to: {})

    Optional ACL entry hash passed to the posix_acl resource. Requires puppet/posix_acl and setfacl on the target node. action: set | add | remove permission: Array of ACL entry strings, e.g. [‘group:wheel:r–’]



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'manifests/file.pp', line 66

define secrets::file (
  Variant[String, Sensitive[String]] $content,
  Variant[String,Integer]            $owner = 'root',
  Variant[String,Integer]            $group = 'root',
  Array                              $notify_services = [],
  Hash                               $posix_acl       = {},
  Boolean                            $selinux_ignore_defaults = false,
  Optional[Stdlib::Absolutepath]     $path     = undef,
  # lint:ignore:optional_default
  Optional[Pattern[/^[0-7]{4}$/]]    $mode     = '0400',
  # lint:endignore
  Optional[String[1]]                $seluser  = undef,
  Optional[String[1]]                $selrole  = undef,
  Optional[String[1]]                $seltype  = undef,
  Optional[String[1]]                $selrange = undef,
) {
  # Resolve target path: explicit $path wins, else $title must be absolute.
  $_path = pick($path, $title)
  assert_type(Stdlib::Absolutepath, $_path) |$expected, $actual| {
    fail("secrets::file[${title}]: 'path' must be an absolute path; got '${_path}'")
  }

  # show_diff and backup are hardcoded. Leaking secrets into reports or the
  # filebucket is not a recoverable mistake.
  file { $_path:
    ensure                  => 'file',
    owner                   => $owner,
    group                   => $group,
    mode                    => $mode,
    content                 => Sensitive($content.unwrap),
    seluser                 => $seluser,
    selrole                 => $selrole,
    seltype                 => $seltype,
    selrange                => $selrange,
    selinux_ignore_defaults => $selinux_ignore_defaults,
    force                   => true,
    show_diff               => false,
    backup                  => false,
  }

  unless empty($notify_services) {
    File[$_path] ~> $notify_services.map |$srv| { Service <| title == $srv |> }
  }

  unless empty($posix_acl) {
    $my_acls = { $_path => $posix_acl }
    create_resources(posix_acl, $my_acls, { 'require' => File[$_path] })
  }
}