{"action":"created","issue":{"url":"https://api.github.com/repos/saltstack/salt/issues/45882","repository_url":"https://api.github.com/repos/saltstack/salt","labels_url":"https://api.github.com/repos/saltstack/salt/issues/45882/labels{/name}","comments_url":"https://api.github.com/repos/saltstack/salt/issues/45882/comments","events_url":"https://api.github.com/repos/saltstack/salt/issues/45882/events","html_url":"https://github.com/saltstack/salt/issues/45882","id":294875153,"number":45882,"title":"Canonical solution for securely transferring data between minions","user":{"login":"Nick2253","id":926554,"avatar_url":"https://avatars0.githubusercontent.com/u/926554?v=4","gravatar_id":"","url":"https://api.github.com/users/Nick2253","html_url":"https://github.com/Nick2253","followers_url":"https://api.github.com/users/Nick2253/followers","following_url":"https://api.github.com/users/Nick2253/following{/other_user}","gists_url":"https://api.github.com/users/Nick2253/gists{/gist_id}","starred_url":"https://api.github.com/users/Nick2253/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Nick2253/subscriptions","organizations_url":"https://api.github.com/users/Nick2253/orgs","repos_url":"https://api.github.com/users/Nick2253/repos","events_url":"https://api.github.com/users/Nick2253/events{/privacy}","received_events_url":"https://api.github.com/users/Nick2253/received_events","type":"User","site_admin":false},"labels":[{"id":48088732,"url":"https://api.github.com/repos/saltstack/salt/labels/Question","name":"Question","color":"942192","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/saltstack/salt/milestones/37","html_url":"https://github.com/saltstack/salt/milestone/37","labels_url":"https://api.github.com/repos/saltstack/salt/milestones/37/labels","id":343741,"number":37,"title":"Blocked","description":"Issues which are blocked in some way, whether they need further discussion, clarification, justification, or are blocked for some other reason.","creator":{"login":"basepi","id":702318,"avatar_url":"https://avatars2.githubusercontent.com/u/702318?v=4","gravatar_id":"","url":"https://api.github.com/users/basepi","html_url":"https://github.com/basepi","followers_url":"https://api.github.com/users/basepi/followers","following_url":"https://api.github.com/users/basepi/following{/other_user}","gists_url":"https://api.github.com/users/basepi/gists{/gist_id}","starred_url":"https://api.github.com/users/basepi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/basepi/subscriptions","organizations_url":"https://api.github.com/users/basepi/orgs","repos_url":"https://api.github.com/users/basepi/repos","events_url":"https://api.github.com/users/basepi/events{/privacy}","received_events_url":"https://api.github.com/users/basepi/received_events","type":"User","site_admin":false},"open_issues":1021,"closed_issues":1971,"state":"open","created_at":"2013-05-28T22:24:12Z","updated_at":"2018-02-08T15:31:30Z","due_on":null,"closed_at":null},"comments":4,"created_at":"2018-02-06T19:00:17Z","updated_at":"2018-02-08T16:26:09Z","closed_at":null,"author_association":"NONE","body":"## Description of Question\r\nI've been trying to determine the canonical solution to the following problem:\r\n- Generate secure data on a first minion.\r\n- Pass the secured data from the first minion to a second minion.\r\n\r\nAn example of this process is generating a Let's Encrypt certificate from a web-accessible client (first minion) for a web-inaccessible client (second minion), and passing the certificate and key to the second minion.  This particular example will become even more important once Let's Encrypt allows wildcard certs at the end of February.\r\n\r\nAnother example of this process is generating an Icinga2 client ticket.  When a new minion (the second minion) is added to the network, the Icinga2 master (the first minion) generates a ticket, and the second minion needs that ticket to complete client setup.\r\n\r\nA further example of this process is a username/password.  Many legacy services are only accessible via usernames/passwords, and they have requirements for regular password changes (usually for regulatory reasons).  These services can be configured to automatically generate a new password (on the first minion), and these passwords need to be send to clients that need them (the second minion).\r\n\r\n### Possible Solutions, and Problems\r\nI have seen a few possible solutions discussed on the internet, but no solution seems to provide all these features:\r\n- Handled entirely by Salt\r\n- Secure the data so that only the master and the two minions know about it\r\n\r\nGenerally speaking, the first part of the problem is easily done in Salt.  Whether with a custom method, a command, etc, it's fairly easy to either create a file, or even a pillar file, containing the secure data on the first minion.  The challenge is the second part:  moving the file securely using Salt.\r\n\r\nI'm assuming that the best way to handle this is transfer the file from the first minion to the master, and then from the master to the second minion.  This assumption is also shared with some of the solutions I've seen below.\r\n\r\n#### `cp.push`\r\n*As suggested in #31863*\r\n\r\nThe general workflow is to use [`cp.push`](https://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.cp.html#salt.modules.cp.push) to send the file from the first minion to the master.  However, `cp.push` uses `salt.transport.Channel.send()`, which is [not guaranteed to be confidential](https://docs.saltstack.com/en/develop/topics/transports/index.html#req-channel).\r\n\r\nIf we could add a \"secure\" flag to the `cp.push` method to use the `crypted_transfer_decode_dictentry`, that would enable a means to securely pass the files to the master.\r\n\r\n#### `event.send`\r\n*As suggested in #27156*\r\n\r\nThe general workflow is to generate the secure data on the first minion, and then trigger an event, passing the secure data from the first minion to the master.  A reactor is triggered on the event, and applies the data to the second minion.\r\n\r\nHowever, this method has the same problems as `cp.push`.  All data passed in events, including pillar data, uses the `.send()` transport.\r\n\r\n#### Salt Mine\r\n*As suggested in #27156, #44564*\r\n\r\nThe general workflow is to create a mine function that takes the secure data from the first minion.  Then, the data can be used by the second minion.\r\n\r\nHowever (other then the general inapplicability of a salt mine for rarely changing data), the Salt Mine's permission schemes do not support the ability for one minion's data to be selectively parsed out to other minions.\r\n\r\n### Concluding Thoughts\r\nI've been trying to research these options, diving into the Salt code for the last couple weeks.  However, I've come up empty handed.  Looking at how this is handled in other configuration management systems, to me, is straightforward.  I can't imagine that this task is impossible in Salt, since everything else I've seen tells me that Salt is very powerful.  I can only assume that I'm making some deep-seated assumption that is creating an implied solution, and forcing me into a narrow box.\r\n\r\nMy goal here is to either (1) learn what I'm missing, and help produce documentation for other new users in my shoes, or (2) bring this issue to the attention of the Salt team, and hopefully contribute to a solution to this problem."},"comment":{"url":"https://api.github.com/repos/saltstack/salt/issues/comments/364166301","html_url":"https://github.com/saltstack/salt/issues/45882#issuecomment-364166301","issue_url":"https://api.github.com/repos/saltstack/salt/issues/45882","id":364166301,"user":{"login":"gtmanfred","id":732321,"avatar_url":"https://avatars0.githubusercontent.com/u/732321?v=4","gravatar_id":"","url":"https://api.github.com/users/gtmanfred","html_url":"https://github.com/gtmanfred","followers_url":"https://api.github.com/users/gtmanfred/followers","following_url":"https://api.github.com/users/gtmanfred/following{/other_user}","gists_url":"https://api.github.com/users/gtmanfred/gists{/gist_id}","starred_url":"https://api.github.com/users/gtmanfred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gtmanfred/subscriptions","organizations_url":"https://api.github.com/users/gtmanfred/orgs","repos_url":"https://api.github.com/users/gtmanfred/repos","events_url":"https://api.github.com/users/gtmanfred/events{/privacy}","received_events_url":"https://api.github.com/users/gtmanfred/received_events","type":"User","site_admin":false},"created_at":"2018-02-08T16:26:09Z","updated_at":"2018-02-08T16:26:09Z","author_association":"OWNER","body":"The vault sdb uses the vault execution module can have acls to allow only certain minions access to the data.\r\n\r\nhttps://docs.saltstack.com/en/latest/ref/modules/all/salt.modules.vault.html\r\n\r\n```\r\nsaltstack/minion/{minion}\r\n```\r\n\r\nAnd then in vault you would only allow each minions role access to whatever data, and then only allow them to read it, and then your minion that generates the variable would have access to pull the data.\r\n\r\nThere are several other modules that could be used but vault is by far the most used, specifically because it is meant as a secret store.\r\n\r\nhttps://docs.saltstack.com/en/latest/ref/sdb/all/index.html"}}
{"actor":{"display_login":"gtmanfred"}}