{"id":15156637,"url":"https://github.com/puppetlabs/puppetlabs-node_encrypt","last_synced_at":"2026-04-08T13:31:26.508Z","repository":{"id":57664156,"uuid":"47938370","full_name":"puppetlabs/puppetlabs-node_encrypt","owner":"puppetlabs","description":"Encrypt secrets inside Puppet catalogs and reports","archived":false,"fork":false,"pushed_at":"2025-11-18T11:16:23.000Z","size":295,"stargazers_count":26,"open_issues_count":3,"forks_count":22,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-01-29T16:37:43.906Z","etag":null,"topics":["hacktoberfest","module","puppet","supported"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/puppetlabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-13T22:06:43.000Z","updated_at":"2025-11-18T11:16:26.000Z","dependencies_parsed_at":"2024-06-18T18:19:21.684Z","dependency_job_id":"0dc86339-50ca-467c-960e-e946f8413ecb","html_url":"https://github.com/puppetlabs/puppetlabs-node_encrypt","commit_stats":{"total_commits":203,"total_committers":16,"mean_commits":12.6875,"dds":0.5369458128078818,"last_synced_commit":"4b94e019936025caab01f46b41c9cbe042f26937"},"previous_names":["binford2k/binford2k-node_encrypt"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/puppetlabs/puppetlabs-node_encrypt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puppetlabs%2Fpuppetlabs-node_encrypt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puppetlabs%2Fpuppetlabs-node_encrypt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puppetlabs%2Fpuppetlabs-node_encrypt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puppetlabs%2Fpuppetlabs-node_encrypt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/puppetlabs","download_url":"https://codeload.github.com/puppetlabs/puppetlabs-node_encrypt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/puppetlabs%2Fpuppetlabs-node_encrypt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31558380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T10:21:54.569Z","status":"ssl_error","status_checked_at":"2026-04-08T10:21:38.171Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","module","puppet","supported"],"created_at":"2024-09-26T19:40:20.751Z","updated_at":"2026-04-08T13:31:26.478Z","avatar_url":"https://github.com/puppetlabs.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `node_encrypt`: over the wire encryption.\n\n1. [Overview](#overview)\n1. [Usage](#usage)\n1. [Ecosystem](#ecosystem)\n1. [License](#license)\n\n## Overview\n\nDo you wish your Puppet catalogs didn't contain plain text secrets? Are you\ntired of limiting access to your Puppet reports because of the passwords clearly\nvisible in the change events? This module will encrypt values for each node\nspecifically, using their own certificates. This means that not only do you not\nhave plain text secrets in the catalog file, but each node can decrypt only its\nown secrets.\n\n\u003cimg src=\"assets/puppet6.png\" alt=\"Puppet 6 logo\" align=\"right\" width=\"125\" height=\"125\"\u003e\n\nWhat precisely does that mean? A resource that looks like the examples below will\nnever have your secrets exposed in the catalog, in any reports, or any other\ncached state files. Any parameter of any resource type may be encrypted  by\nsimply annotating your secret string with a function call. **This relies on\nDeferred execution functions in Puppet 6**. If you're running Puppet 5 or\nbelow, then pin this module to `v0.4.1` or older for backwards compatibility.\n\n```Puppet\nuser { 'erwin':\n  ensure   =\u003e present,\n  password =\u003e '{vT6YcbBhX.LL6s8'.node_encrypt::secret\n}\n\nfile { '/etc/secretfile.cfg':\n  ensure  =\u003e file,\n  content =\u003e 'this string will be encrypted in your catalog'.node_encrypt::secret\n}\n\nfile { '/etc/another_secretfile.cfg':\n  ensure  =\u003e file,\n  content =\u003e template('path/to/template.erb').node_encrypt::secret,\n}\n\n$token = lookup('application_token')\nexec { 'authenticate service':\n  command =\u003e '/bin/application-register ${token}'.node_encrypt::secret,\n}\n```\n\nThis also comes with a Puppet Face which can be used to encrypt content for a node\nand then decrypt it on that node. If you like, you may also paste the ciphertext\ninto your manifest or Hiera datafiles and then manually invoke the `node_decrypt()`\nfunction as needed.\n\n## Suitability\n\nPlease note that `node_encrypt` is ***not a security panacea***. It will encrypt\nyour secrets in the catalog file on disk using the node's certificate, but the\ncorresponding private key is also on disk in clear text. This means that if an\nattacker gains root level access to your filesystem, then they can likely read\nboth the encrypted secrets and the key required to decrypt them.\n\n| ⚠️ **Warning:** |\n|-----------------|\n| *`node_encrypt` will only protect you in cases where an attacker has access to the catalog file, but not to the node's private certificate.* |\n\nSome of the cases protected by `node_encrypt` might include:\n\n* Using the catalog files for certain kinds of [impact analysis](https://dev.to/camptocamp-ops/automated-puppet-impact-analysis-1c1)\n* Making catalogs available for troubleshooting with catalog diff\n* Integrations that retrieve catalogs from [PuppetDB via API](https://puppet.com/docs/puppetdb/latest/api/query/v4/catalogs.html)\n\nIf you have more stringent security requirements, we suggest integrating with a purpose\nbuilt secret server. See [docs](https://puppet.com/docs/puppet/latest/integrations_with_secret_stores.html) for more details.\n\n\n## Usage\n\n* `node_encrypt::secret()`\n    * This function encrypts a string on the server, and then decrypts it on the\n      agent during catalog application.\n    * Example: `'secret string'.node_encrypt::secret`\n* `redact()`\n    * This Puppet function allows you to remove from the catalog the value of a\n      parameter that a class was called with.\n        * The name of the parameter to redact.\n        * The message to replace the parameter's value with. (optional)\n* `puppet node encrypt`\n    * This is a Puppet Face that generates encrypted ciphertext on the command line.\n    * `puppet node encrypt -t testhost.example.com \"encrypt some text\"`\n* `puppet node decrypt`\n    * This is a Puppet Face that decrypts ciphertext on the command line. It can\n      be useful in command-line scripts.\n* `node_decrypt()`\n    * This is a Puppet function used to decrypt encrypted text on the agent.\n      You'll only need to use this if you save encrypted content in your manifests\n      or Hiera data files.\n    * Example: `content =\u003e Deferred(\"node_decrypt\", [$encrypted_content])`\n* `node_encrypt::certificates`\n    * This class will synchronize certificates to all compile servers.\n    * Generally not needed, unless the `clientcert_pem` fact fails for some reason.\n\nThe simplest usage is like the example shown in the [Overview](#overview). This\ndefined type accepts most of the standard file parameters and simply encrypts the\nfile contents in the catalog.\n\n\n### Function usage:\n\n#### `node_decrypt($string)`\n\nThis function simply decrypts the ciphertext passed to it using the agent's own\ncertificate. It is generally only useful as a Deferred function on Puppet 6+.\n\n```Puppet\n$encrypted = lookup('encrypted_foo')\nfile { '/etc/something/or/other.conf:\n  ensure  =\u003e file,\n  owner   =\u003e 'root',\n  group   =\u003e 'root',\n  mode    =\u003e '0600',\n  content =\u003e Deferred(\"node_decrypt\", [$encrypted]),\n}\n```\n\n\n#### `redact($parameter, $replacewith)`\n\nThis function will modify the catalog during compilation to remove the named\nparameter from the class from which it was called. For example, if you wrote a\nclass named `foo` and called `redact('bar')` from within that class, then the\ncatalog would not record the value of `bar` that `foo` was called with.\n\n```Puppet\nclass foo($bar) {\n  # this call will display the proper output, but because it's not a resource\n  # the string won't exist in the catalog.\n  notice(\"Class['foo'] was called with param ${bar}\")\n\n  # but the catalog won't record what the passed in param was.\n  redact('bar')\n}\n\nclass { 'foo':\n  bar =\u003e 'this will not appear in the catalog',\n}\n```\n\n**Warning**: If you use that parameter to declare other classes or resources,\nthen you must take further action to remove the parameter from those declarations!\n\nThis takes an optional second parameter of the value to replace the original\nparameter declaration with. This parameter is required if the class declares\na type that is not `String` for the parameter you're redacting.\n\n\n### Using the command line decryption tool\n\nThis comes with a Puppet Face that can encrypt or decrypt on the command line.\nYou can use this in your own scripts via several methods. The ciphertext can be\ngenerated on the CA or any compile server using the `puppet node encrypt`\ncommand.\n\n    # puppet node encrypt -t testhost.puppetlabs.vm \"encrypt some text\"\n    -----BEGIN PKCS7-----\n    MIIMqwYJKoZIhvcNAQcDoIIMnDCCDJgCAQAxggJ7MIICdwIBADBfMFoxWDBWBgNV\n    BAMMT1B1cHBldCBDQSBnZW5lcmF0ZWQgb24gcHVwcGV0ZmFjdG9yeS5wdXBwZXRs\n    [...]\n    MbxinAGtO0eF4i8ova9MJykDPe600IY2b9ZY4mIskDqvHS9bVoK4fJGuRWAXiVBY\n    bFaZ36l90LkyLLrrSfjah/Tdqd8cHrphofsWVFWBmM1uErX1jBuuzngIehm40pN7\n    ClVbGy9Ow3zado1spWfDwekLoiU5imk77J9POy0X8w==\n    -----END PKCS7-----\n\nDecrypting on the agent is just as easy, though a bit more flexible. For\nconvenience in these examples, let's assume that we've set a variable like such:\n\n    # export SECRET=$(puppet node encrypt -t testhost.puppetlabs.vm \"your mother was a hamster\")\n\nYou can then decrypt this data by:\n\n* Passing data directly using the `--data` option:\n    * `puppet node decrypt --data \"${SECRET}\"`\n    * On some platforms, this may exceed command length limits!\n* Setting data in an environment variable and passing the name:\n    * `puppet node decrypt --env SECRET`\n* Piping data to STDIN:\n    * `echo \"${SECRET}\" | puppet node decrypt`\n    * `cat /file/with/encrypted/blob.txt | puppet node decrypt`\n\n\n### Automatically distributing certificates to compile servers\n\nThe agent should send its public certificate as a custom `clientcert_pem` fact,\nmaking this a seamless zero-config process. In the case that doesn't work, you\ncan distribute certificates to your compile servers using the\n`node_encrypt::certificates` class so that encryption works from all compile\nservers. Please be aware that **this class will create a fileserver mount on the\nCA node** making public certificates available for download by all nodes.\n\nClassify all your servers, including the CA or Primary Server, with this class.\nThis will ensure that all server have all agents' public certificates.\n\n**Note**:\u003cbr /\u003e\nIf this is applied to all nodes in your infrastructure then all agents will have all\npublic certificates synched. This is not a security risk, as public certificates are\ndesigned to be shared widely, but it is something you should be aware of. If you wish\nto prevent that, just make sure to classify only your servers.\n\nParameters:\n\n* [*ca_server*]\n    * If the CA autodetection fails, then you can specify the $fqdn of the CA server here.\n\n* [*sort_order*]\n    * If you've customized your HOCON-based `auth.conf`, set the appropriate sort\n      order here. The default rule's weight is 500, so this parameter defaults to\n      `300` to ensure that it overrides the default.\n\n\n### Using on serverless infrastructures\n\nFor the most part, `node_encrypt` doesn't have as much value in a serverless\nsetup. When the agent is compiling its own catalog, there's no cached catalog or\nnetwork transfer. Nevertheless, there are use cases for it. For example, if you\nhave a report server configured, or are submitting catalogs \u0026 reports to PuppetDB,\nyou likely want to keep secrets hidden.\n\n`node_encrypt` won't work out of the box on a serverless node because it relies\non the existence of the CA certificates. But it's easy to generate these\ncertificates so that it will work. Keep in mind that without the full CA\ninfrastructure, no other node will be able to decrypt these secrets.\n\nNote that this functionality was moved to the `puppetserver` application\nin Puppet 6.x, so you'll need Puppet 5.x to generate this certificate.\n\n```\n$ rm -rf $(puppet config print ssldir --section server)/*\n$ puppet cert list -a\n$ puppet cert --generate ${puppet config print certname} --dns_alt_names \"$(puppet config print dns_alt_names)\"\n```\n\n\n## Ecosystem\n\n#### How is this different from the new `Sensitive` type?\n\nAs of Puppet 4.6, [the core language supports a `Sensitive` type](https://puppet.com/docs/puppet/5.3/lang_data_sensitive.html).\nThis type marks data with a flag that prevents the components of the Puppet and\nPuppet Enterprise stack from inadvertently displaying the value. For example, a\nstring that's marked as `Sensitive` will not display in reports or in the PE\nConsole.\n\n*Unfortunately, it still exists as plain text in the catalog.* The `node_encrypt`\nmodule encrypts data before it goes into the catalog, and it's only decrypted as\nit's being written to disk.\n\n\n#### What about [Hiera eyaml](https://github.com/TomPoulton/hiera-eyaml)?\n\nDoes this project replace that tool?\n\nNot at all. They exist in different problem spaces.  Hiera eyaml is intended to\nprotect your secrets on-disk and in your repository.  With Hiera eyaml, you can\nadd secrets to your codebase without having to secure the entire codebase.\nHaving access to the code doesn't mean having access to the secrets in that code.\n\nBut the secrets are still exposed in the catalog and in reports. This means you\nshould be protecting them as well. `node_encrypt` addresses that problem. The two\nprojects happily coexist. You can (and should) use `eyaml` to store your secrets\non disk, while you use `node_encrypt` to protect the rest of the pipeline.\n\n#### Integration with other tools\n\nThis was designed to make it easy to integrate support into other tooling. For\nexample, [this pull request](https://github.com/richardc/puppet-datacat/pull/17/files)\nadds transparent encryption support to _rc's popular `datacat` module.\n\n#### Testing with [Onceover](https://github.com/dylanratcliffe/onceover)\n\nIf you use Onceover to test your puppet roles, you'll experience compilation failures\nwhen using this module as it won't be able to find the private keys it expects.\n\n```\nEvaluation Error: Error while evaluating a Resource Statement, Evaluation Error: Error while evaluating a Function Call, Not a directory @ rb_sysopen - /dev/null/ssl/private_keys/example.com.pem\n```\n\nIn your onceover.yaml file, mock the `node_encrypt` function as follows.\n\n```yaml\nfunctions:\n  node_encrypt:\n    returns: '-----BEGIN PKCS7----- MOCKED_DATA'\n```\n\n\n\n## Limitations\n\nFor an extensive list of supported operating systems, see [metadata.json](https://github.com/puppetlabs/puppetlabs-node_encrypt/blob/main/metadata.json)\n\n## License\n\nThis codebase is licensed under the Apache2.0 licensing, however due to the nature of the codebase the open source dependencies may also use a combination of [AGPL](https://opensource.org/license/agpl-v3/), [BSD-2](https://opensource.org/license/bsd-2-clause/), [BSD-3](https://opensource.org/license/bsd-3-clause/), [GPL2.0](https://opensource.org/license/gpl-2-0/), [LGPL](https://opensource.org/license/lgpl-3-0/), [MIT](https://opensource.org/license/mit/) and [MPL](https://opensource.org/license/mpl-2-0/) Licensing.\n\n## Disclaimer\n\nI take no liability for the use of this module. As this uses standard Ruby and\nOpenSSL libraries, it should work anywhere Puppet itself does. I have not yet\nvalidated on anything other than CentOS, though.\n\n## Authors\n\nThis module is a continuation of [binford2k/node_encrypt](https://forge.puppet.com/modules/binford2k/node_encrypt/readme) which was developed by [Ben Ford](https://github.com/binford2k). Thank you to all of our contributors.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpuppetlabs%2Fpuppetlabs-node_encrypt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpuppetlabs%2Fpuppetlabs-node_encrypt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpuppetlabs%2Fpuppetlabs-node_encrypt/lists"}