{"id":21745152,"url":"https://github.com/zuazo/chef-encrypted-attributes","last_synced_at":"2025-04-13T05:12:22.878Z","repository":{"id":17218444,"uuid":"19987188","full_name":"zuazo/chef-encrypted-attributes","owner":"zuazo","description":"Chef plugin to add Node encrypted attributes support using client keys.","archived":false,"fork":false,"pushed_at":"2016-09-15T19:31:27.000Z","size":689,"stargazers_count":6,"open_issues_count":1,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-26T03:04:27.016Z","etag":null,"topics":["chef","credentials","devops","encrypted-attributes","encryption","gcm","keys","passwords","pki","plugin","secrets","security"],"latest_commit_sha":null,"homepage":"https://zuazo.github.io/chef-encrypted-attributes/","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/zuazo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-05-20T15:48:35.000Z","updated_at":"2017-07-28T07:02:23.000Z","dependencies_parsed_at":"2022-09-07T07:11:11.138Z","dependency_job_id":null,"html_url":"https://github.com/zuazo/chef-encrypted-attributes","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fchef-encrypted-attributes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fchef-encrypted-attributes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fchef-encrypted-attributes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zuazo%2Fchef-encrypted-attributes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zuazo","download_url":"https://codeload.github.com/zuazo/chef-encrypted-attributes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248665743,"owners_count":21142123,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["chef","credentials","devops","encrypted-attributes","encryption","gcm","keys","passwords","pki","plugin","secrets","security"],"created_at":"2024-11-26T07:13:46.615Z","updated_at":"2025-04-13T05:12:22.853Z","avatar_url":"https://github.com/zuazo.png","language":"Ruby","readme":"# Chef-Encrypted-Attributes\n[![Gem Version](http://img.shields.io/gem/v/chef-encrypted-attributes.svg?style=flat)](http://badge.fury.io/rb/chef-encrypted-attributes)\n[![GitHub](http://img.shields.io/badge/github-zuazo/chef--encrypted--attributes-blue.svg?style=flat)](https://github.com/zuazo/chef-encrypted-attributes)\n[![License](https://img.shields.io/github/license/zuazo/chef-encrypted-attributes.svg?style=flat)](#license-and-author)\n\n[![Dependency Status](http://img.shields.io/gemnasium/zuazo/chef-encrypted-attributes.svg?style=flat)](https://gemnasium.com/zuazo/chef-encrypted-attributes)\n[![Code Climate](http://img.shields.io/codeclimate/github/zuazo/chef-encrypted-attributes.svg?style=flat)](https://codeclimate.com/github/zuazo/chef-encrypted-attributes)\n[![Build Status](http://img.shields.io/travis/zuazo/chef-encrypted-attributes.svg?style=flat)](https://travis-ci.org/zuazo/chef-encrypted-attributes)\n[![Coverage Status](http://img.shields.io/coveralls/zuazo/chef-encrypted-attributes.svg?style=flat)](https://coveralls.io/r/zuazo/chef-encrypted-attributes?branch=master)\n[![Inline docs](http://inch-ci.org/github/zuazo/chef-encrypted-attributes.svg?branch=master\u0026style=flat)](http://inch-ci.org/github/zuazo/chef-encrypted-attributes)\n\n[Chef](https://www.chef.io/) plugin to add Node encrypted attributes support using client keys.\n\nWe recommend using the [`encrypted_attributes`](https://supermarket.chef.io/cookbooks/encrypted_attributes) cookbook for easy installation.\n\n## Description\n\nNode attributes are encrypted using chef client and user keys with public key infrastructure (PKI). You can choose which clients, nodes or users will be able to read the attribute.\n\n*Chef Nodes* with read access can be specified using a `node_search` query. In case new nodes are added or removed, the data will be re-encrypted in the next *Chef Run* of the encrypting node (using the `#update` method shown below). Similarly, a `client_search` query can be used to allow *Chef Clients* to read the attribute.\n\n## Requirements\n\n* Ruby `\u003e= 2.0`\n* Chef Client `~\u003e 11.8`\n* yajl_ruby `~\u003e 1.1` or ffi_yajl `\u003e= 1.0, \u003c3.0` (included with Chef)\n* If you want to use protocol version 2 to use [GCM](http://en.wikipedia.org/wiki/Galois/Counter_Mode) (disabled by default):\n * Ruby `\u003e= 2`.\n * OpenSSL `\u003e= 1.0.1`.\n\n## Usage in Recipes\n\nBefore reading all the documentation below, we recommend you take a look at the [`encrypted_attributes` cookbook's helper libraries](https://github.com/zuazo/encrypted_attributes-cookbook#helper-libraries). Those libraries are easier to use than the underlying API and cover the most common use cases.\n\n### Installing and Including the Gem\n\nYou need to install and include the `chef-encrypted-attributes` gem before using encrypted attributes inside a cookbook.\n\n```ruby\nchef_gem 'chef-encrypted-attributes'\nrequire 'chef/encrypted_attributes'\n```\n\n### Typical Example\n\nIn the following example we save a simple FTP user password.\n\n```ruby\nchef_gem 'chef-encrypted-attributes'\nrequire 'chef/encrypted_attributes'\n\n# include the #secure_password method\nChef::Recipe.send(:include, Opscode::OpenSSL::Password)\n\nif Chef::EncryptedAttribute.exist?(node['myapp']['ftp_password'])\n  # update with the new keys\n  Chef::EncryptedAttribute.update(node.set['myapp']['ftp_password'])\n\n  # read the password\n  ftp_pass = Chef::EncryptedAttribute.load(node['myapp']['ftp_password'])\nelse\n  # create the password and save it\n  ftp_pass = secure_password\n  node.set['myapp']['ftp_password'] = Chef::EncryptedAttribute.create(ftp_pass)\nend\n\n# use `ftp_pass` for something here ...\n```\n\n**Note:** This example requires the [`openssl`](https://supermarket.chef.io/cookbooks/openssl) cookbook.\n\n### Minimal Write Only Example\n\nIn this example we only need to save some data from the local node and read it from another:\n\n```ruby\nchef_gem 'chef-encrypted-attributes'\nrequire 'chef/encrypted_attributes'\n\n# Allow all admin clients to read the attributes encrypted by me\nChef::Config[:encrypted_attributes][:client_search] = 'admin:true'\n\n# Allow all webapp nodes to read the attributes encrypted by me\nChef::Config[:encrypted_attributes][:node_search] = 'role:webapp'\n\nif Chef::EncryptedAttribute.exist?(node['myapp']['encrypted_data'])\n  # we can used #load here as above if we need the `encrypted_data` outside\n  # this `if`\n\n  # update with the new keys\n  Chef::EncryptedAttribute.update(node.set['myapp']['encrypted_data'])\nelse\n  # create the data, encrypt and save it\n  data_to_encrypt = # ....\n  node.set['myapp']['encrypted_data'] =\n    Chef::EncryptedAttribute.create(data_to_encrypt)\nend\n```\n\nThen we can read this attribute from another allowed node (a `'role:webapp'` node):\n\n```ruby\ninclude_recipe 'encrypted_attributes'\n# Expose the public key for encryption\ninclude_recipe 'encrypted_attributes::expose_key'\n\nif Chef::EncryptedAttribute.exist_on_node?(\n     'random.example.com', %w(myapp encrypted_data)\n   )\n  data = Chef::EncryptedAttribute.load_from_node(\n    'random.example.com', %w(myapp encrypted_data)\n  )\n\n  # use `data` for something here ...\nend\n```\n\n**Note:** Be careful when using `#exist_on_node?` and `#load_from_node` and remember passing the attribute path to read as **Array of Strings** ~~instead of using `node[...]` (which points to the local node)~~.\n\n### Example Using User Keys Data Bag\n\nSuppose we want to store users public keys in a data bag and give them access to the attributes. This can be a workaround for the [Chef Users Limitation](#chef-user-keys-access-limitation) problem.\n\nYou need to create a Data Bag Item with a content similar to the following:\n\n```json\n{\n  \"id\": \"chef_users\",\n  \"bob\": \"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFA...\",\n  \"alice\": \"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFA...\"\n}\n```\n\nThis data bag will contain the user public keys retrieved with `knife user show USER -a public_key -f json`.\n\nThen, from a recipe, you can read this user keys and allow them to read the attributes.\n\n```ruby\nchef_gem 'chef-encrypted-attributes'\nrequire 'chef/encrypted_attributes'\n\nchef_users = Chef::DataBagItem.load('global_data_bag', 'chef_users')\n# remove the data bag \"id\" to avoid to confuse it with a user:\nchef_users.delete('id')\n\nChef::Log.debug(\n  \"Chef Users able to read the Encrypted Attributes: #{chef_users.keys.inspect}\"\n)\nChef::Config[:encrypted_attributes][:keys] = chef_users.values\n\n# if Chef::EncryptedAttribute.exist?(...)\n#   Chef::EncryptedAttribute.update(...)\n# else\n#   node.set[...][...] = Chef::EncryptedAttribute.create(...)\n# ...\n```\n\n**Note:** This data bag does **not** need to be **encrypted**, because it only stores **public keys**.\n\n## Chef::EncryptedAttribute API\n\nSee the [API documentation](http://www.rubydoc.info/gems/chef-encrypted-attributes/Chef/EncryptedAttribute/API.html) for a more detailed information about `Chef::EncryptedAttribute` class and its methods.\n\n## Chef User Keys Access Limitation\n\nKeep in mind that, from a Chef Node, *Chef User* *public keys* are inaccessible. So you have to pass them in raw mode in the recipe if you need any *Chef User* to be able to use the encrypted attributes (this is **required for** example to use the **knife commands** included in this gem, as knife is usually used by *Chef Users*). Summarizing, Chef Node inside a recipe (using its *Chef Client* key) will not be able to retrieve the *Chef Users* *public keys*, so you need to pass them using the `[:keys]` configuration value.\n\nChef Nodes (Clients) with *admin* privileges do have access to user public keys, but in most cases this is not a recommended practice.\n\nSee the [Example Using User Keys Data Bag](#example-using-user-keys-data-bag) section for a workaround. You can use the [`encrypted_attributes::users_data_bag`](https://supermarket.chef.io/cookbooks/encrypted_attributes#encrypted_attributes::users_data_bag) recipe for this.\n\n**Note:** *Chef Clients* usually are Chef Nodes and *chef-validation*/*chef-webui* keys. *Chef Users* usually are knife users. The main difference between *Chef Users* and *Chef Clients* is that the former are able to log in via *web-ui* (has a password).\n\n## Chef Client Keys Access Limitation\n\n*Chef Client* *public keys* has a [similar problem to the user keys](#chef-user-keys-access-limitation), you cannot retrieve them from a Chef Node.\n\nTo fix this limitation you should expose de *Chef Client* *public key* in the `node['public_key']` attribute. You can include the [`encrypted_attributes::expose_key`](https://supermarket.chef.io/cookbooks/encrypted_attributes#encrypted_attributes::expose_key) recipe for this. You need to include this recipe in the *Chef Nodes* that require read privileges on the encrypted attributes.\n\nExposing the public key through attributes should not be considered a security breach, so it's not a problem to include it on all machines.\n\n## Maximum Number of Nodes\n\nThis gem is ready to be used with Chef Servers that have less than `1000` nodes by default. You can increase this limit setting the `search_max_rows` configuration option:\n\n```ruby\nChef::Config[:encrypted_attributes][:search_max_rows] = 50_000\n```\n\n## Knife Commands\n\nSee the [KNIFE.md](http://www.rubydoc.info/gems/chef-encrypted-attributes/file/KNIFE.md) file.\n\n## Internal Low Level Documentation\n\nThe cryptographic systems used are documented in the following classes:\n\n* [EncryptedMash](http://www.rubydoc.info/gems/chef-encrypted-attributes/Chef/EncryptedAttribute/EncryptedMash)\n * [EncryptedMash::Version0](http://www.rubydoc.info/gems/chef-encrypted-attributes/Chef/EncryptedAttribute/EncryptedMash/Version0)\n * [EncryptedMash::Version1](http://www.rubydoc.info/gems/chef-encrypted-attributes/Chef/EncryptedAttribute/EncryptedMash/Version1)\n * [EncryptedMash::Version2](http://www.rubydoc.info/gems/chef-encrypted-attributes/Chef/EncryptedAttribute/EncryptedMash/Version2)\n\nSee the [official gem documentation](http://www.rubydoc.info/gems/chef-encrypted-attributes/) for more information.\n\n## Using Signed Gems\n\nThe `chef-encrypted-attributes` gem is cryptographically signed by Onddo Labs's certificate, which identifies as *xabier@zuazo.org*. You can obtain the official signature here:\n\n    https://raw.github.com/zuazo/chef-encrypted-attributes/master/certs/xabier_zuazo.crt\n\nTo be sure the gem you install has not been tampered with:\n\n    $ gem cert --add \u003c(curl -Ls https://raw.github.com/zuazo/chef-encrypted-attributes/master/certs/xabier_zuazo.crt)\n    $ gem install chef-encrypted-attributes -P MediumSecurity\n\nThe *MediumSecurity* trust profile will verify signed gems, but allow the installation of unsigned dependencies. This is necessary because not all of `chef-encrypted-attributes`'s dependencies are signed, so we cannot use *HighSecurity*.\n\nWe recommend to remove our certificate after the gem has been successfully verified and installed:\n\n    $ gem cert --remove '/cn=xabier/dc=zuazo/dc=org'\n\n## Security Notes\n\nAll the cryptographic systems and algorithms used by `chef-encrypted-attributes` are carefully described in the [internal documentation](#internal-low-level-documentation) for public review. The code was originally based on *Encrypted Data Bags* and [chef-vault](https://github.com/Nordstrom/chef-vault) implementations, then improved.\n\nStill, this gem should be considered experimental until audited by professional cryptographers.\n\n## Reporting Security Problems\n\nIf you have discovered a bug in `chef-encrypted-attributes` of a sensitive nature, i.e.  one which can compromise the security of `chef-encrypted-attributes` users, you can report it securely by sending a GPG encrypted message. Please use the following key:\n\n    https://raw.github.com/zuazo/chef-encrypted-attributes/master/zuazo.gpg\n\nThe key fingerprint is (or should be):\n\n    ADAE EEFC BD78 6CBB B76B  1662 2195 FF19 5324 14AB\n\n## Testing\n\nSee [TESTING.md](https://github.com/zuazo/chef-encrypted-attributes/blob/master/TESTING.md).\n\n## Contributing\n\nPlease do not hesitate to [open an issue](https://github.com/zuazo/chef-encrypted-attributes/issues/new) with any questions or problems.\n\nSee [CONTRIBUTING.md](https://github.com/zuazo/chef-encrypted-attributes/blob/master/CONTRIBUTING.md).\n\n## TODO\n\nSee [TODO.md](https://github.com/zuazo/chef-encrypted-attributes/blob/master/TODO.md).\n\n## License and Author\n\n|                      |                                          |\n|:---------------------|:-----------------------------------------|\n| **Author:**          | [Xabier de Zuazo](https://github.com/zuazo) (\u003cxabier@zuazo.org\u003e)\n| **Contributor:**     | [Josh Kalderimis](https://github.com/joshk)\n| **Contributor:**     | [Crystal Hsiung](https://github.com/chhsiung)\n| **Contributor:**     | [Lisa Danz](https://github.com/ldanz)\n| **Contributor:**     | [Eric Blevins](https://github.com/e100)\n| **Copyright:**       | Copyright (c) 2016 Xabier de Zuazo\n| **Copyright:**       | Copyright (c) 2014-2015 Onddo Labs, SL.\n| **License:**         | Apache License, Version 2.0\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n    \n        http://www.apache.org/licenses/LICENSE-2.0\n    \n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzuazo%2Fchef-encrypted-attributes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzuazo%2Fchef-encrypted-attributes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzuazo%2Fchef-encrypted-attributes/lists"}