> > ... >
> Sure, an example: > > A web application needs creds (secrets) in order to access a 3rd party > api. These creds need to exist in a config file on the webserver/instance. > As a user, you/I know what the secrets are, but now we need to share them > with the web application, and only the web application in order for the > webapp to connect to the 3rd party api. > > Who are we hiding the information from? > > Considering the above example, restricting access to the “secrets” from > any entity outside of the one that would need access to them to provision > them seems like a reasonable approach. That being said, I feel like access > restrictions should be at the charm/layer level. > So how does a charm/layer prove who it is, such that nobody else can do that proof? Juju tracks what charms are deployed to what machine, and each unit agent ends up having its own login back to the Controller. However, all charms hooks are run as 'root' on the machine (they sort of have to, because they need to do stuff like install software). Which means they can read any files that exist on the machine. So there is very little we could do at the 'layer' level, aside from pretend that the information couldn't be read. (We could have a secret key for a layer, but where could that layer store its secret that any other software running as root on that machine couldn't get access to.) You also have to be a little careful if you ever install 2 charms on the same machine (juju deploy foo --to 1), because then both bits of software could read the secrets that were for the other software. (Worst case, they just read the configuration of the actual service, which must have some way to get the unencrypted form, or it couldn't do its job.) As is, we don't allow agents to read the data for other agents. (The agent for machine-1 could ask for the details of machine-2, but will get told EPERM). If we aren't hiding the values from the *user* then simple application config is already secret. There may be bugs, but by design the only thing that can read the config for an application is the agents for the units of that application, the controller itself, and the user. Now, there is a case for maybe storing the secrets encrypted on the controller, but again, all of the information for how to get the secrets out have to be in the system, so that *someone* could make use of them. One thought, we could improve things slightly over the status quo if we had each agent create a public/private key pair and register it, and then anything flagged 'secret' gets encrypted with the agents public key, and the agent stores its private key somewhere on the machine-local disk. Then when a user enters secrets, we encrypt the values with that public key, and not even the controller has access anymore. Still can't do per-layer secrets (cause where can a layer store a secret that another layer in the same charm can't get to it)? But we could cut out the ability for anything but software running on that machine to read it. I'm not sure if the cost/benefit is really there, as if you want to deploy 2 units of the software, you have to re-encrypt the original settings for the second unit, and if the Controller doesn't have access to the original text, then it can't encrypt it for the second unit. The User has to re-enter the software. Likely we also need a public/private key that the User tracks, if they ever want to 'get' the value back. And I guess we could make it so 'add-unit' interacts with the User, who can decrypt the content with the User's key, and then encrypt it back with the agents public key. Its a lot of hassle, with the one advantage that getting access to the Controller doesn't give you access to the secrets of all software that has been configured. But I have the feeling that for your actual use case, just the fact that the Controller doesn't let anyone but the agent-in-charge-of-that-application read the values for that application is actually enough. > Two possibilities I’ve thought of: > > A) Layer Sensitive Secrets - I’m thinking a secret might only be readable > to the layer in which it is configured to be used. A secret could be > context sensitive to the :, such that when you set a secret in a model, you > are setting it such that it can only be accessed by a named layer in named > charm. > > B) Shared Model Secrets - Less restrictive “secrets”, accessible globally, > at the model level. > > Are we hiding information from the Juju users? > > When a secret is set, it could be hashed before being stored in the > database, then other users who are members of the same model wouldn’t be > able to see what the secret was, but they could see that it exists by > listing secrets. > > Are we trying to hide information from other processes on the same > machines as the agents? > > I think the process isolation would come along for the ride inherently as > long as processes and directories have their permissions locked down > appropriately upon setup/configuration. > > Also, who generates and holds the keys? > > Here’s what I’m thinking, consider the following hypothetical situation: > > You basically want an action to do the following: > > sudo htpasswd -c /etc/nginx/htpasswd.users kibanaadmin > > Cloud admin of company X runs a Kibana instance that he desires to enhance > access control on. Kibana is deployed via Juju. Seeing as Juju “secrets” > exist, the cloud admin of company X can use the Juju CLI to set the users > and passwords (secrets) of those he desires to grant access to the Kibana > dashboard. The cloud admin wants to define the “secrets” in a .yaml file, > and feed it to his Juju environment using the juju add-secrets command, > after which he will trigger an “action” to write out the htpasswd file with > the latest secrets associated with the environment. After running juju > add-secrets, Juju hashes the secret values and stores them in the model > context of the controller, only to be unencrypted (or read) upon a call to > their getter function, called by the layer or charm whom they are > configured to in secrets.yaml. e.g. > > 1. > > secrets.yaml > > secrets: > kibana: > htpasswd-user: someuser > htpasswd-pass: somepassword > > 2. > > juju add-secret lxd-dev-controller:my-lxd-model -f secrets.yaml > 3. rm secrets.yaml > 4. juju run-action kibana/0 htpasswd access='allow' > > On #1 the user defines the secrets for the controller:model:charm in the > secrets.yaml. > On #2 the user updates the controller with the secrets to the > controller:model:charm, juju hashes the secrets and stores them in the > model context of the controller. > On #3 the user deletes the secrets.yaml file as he want to ensure no one > will be able to view the secrets if access is breached on his local machine. > On #4 the user runs an action that decrypts the secrets stored in the > state server, and puts them in the .htaccess file on the server. > > Starting to feel like I am rambling. Hopefully this will help clarify what > I am thinking a "secret" might be! > > Thoughts? > Hiding secrets from the user who uploaded them is possible, but poses some fairly significant usability costs. If we want to make the controller not a fault point, then you can see my above thoughts around creating per-unit and user public/private keys. A cheaper thing could be 'write only' values, which lets you set a config value, but doesn't let the user see it. We already have this idea floating around for read-only vs admin users. (So I can give you read-only access to my Model, but that doesn't let you read the private ssl keyfile.) This would take it one step further where you can't read it either. This generally suffers from 'do I have the right ssl cert there?' and not being able to read the value that you put there. Any sort of 'encrypting in the database' starts to suffer from 'where is the key that lets you read it', And how do you make sure that only the right places have access to that key. If you encrypt the whole database, but the keys for that database live next to it, you haven't really made anything more secure. John =:-> > > On Sun, Jul 24, 2016 at 1:53 PM, Tim Penhey <tim.pen...@canonical.com> > wrote: > > On 25/07/16 06:32, James Beedy wrote: >> >>> Proposed Solution: Juju Secrets >>> >>> To give Juju a combative edge on the privacy pinwheel of secrets >>> distribution in the realm of bleeding edge devops tooling, behold my >>> hypothetical proposed solution: |juju secrets|. >>> Juju secrets could be used like so: >>> |juju add-secret mycloud:mymodel -f secrets.yaml| >>> >>> I know you guys are pressing hard to get 2.0 out the door, so please >>> don’t mind my nonsense here. I just wanted to throw the idea out there >>> and possibly get some feedback, and have others weigh in on this topic. >>> >>> Thoughts? >>> >> >> Interesting idea. How would this really work in practice? >> >> For the secrets to be any use, the units need to be able to get access to >> the information right? >> >> Who are we hiding the information from? This is always a key question >> that needs to be answered in order to choose a good solution. >> >> Are we hiding information from the Juju users? >> >> Are we trying to hide information from other processes on the same >> machines as the agents? >> >> Also, who generates and holds the keys? >> >> Just some more questions. >> >> >> Tim >> > > > -- > Juju-dev mailing list > Juju-dev@lists.ubuntu.com > Modify settings or unsubscribe at: https://lists.ubuntu.com/ > mailman/listinfo/juju-dev > >
-- Juju-dev mailing list Juju-dev@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/juju-dev