Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Secret-specific protos #1511

Merged
merged 9 commits into from
Sep 23, 2016
Merged

Secret-specific protos #1511

merged 9 commits into from
Sep 23, 2016

Conversation

cyli
Copy link
Contributor

@cyli cyli commented Sep 7, 2016

This does not include any implementation yet - the goal is:

  1. merge Use assignments instead of tasks #1508
  2. merge this
  3. open 1-2 secrets-implementation PRs


Meta meta = 2 [(gogoproto.nullable) = false];

map<string, SecretData> secret_data = 3;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please document this field, including the meaning of the map keys.

@codecov-io
Copy link

codecov-io commented Sep 7, 2016

Current coverage is 54.06% (diff: 0.00%)

Merging #1511 into master will increase coverage by 0.03%

@@             master      #1511   diff @@
==========================================
  Files            82         83     +1   
  Lines         13605      13613     +8   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           7351       7360     +9   
+ Misses         5261       5258     -3   
- Partials        993        995     +2   

Sunburst

Powered by Codecov. Last update 8b9cdbb...ac092de

string digest = 4;

// Size represents the size of the secret
int32 size = 5 [(gogoproto.customname) = "SecretSize"];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be uint32, or do negative values have a valid meaning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, uint32, thank you!

repeated Secret secrets = 1;
}

// Note CreateSecretRequest does not contain a SecretSpec, since that can contain multiple SecretData objects, which have digests
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't look right; CreateSecretRequest does contain a SecretSpec.

@cyli cyli force-pushed the secret-protos branch 2 times, most recently from a691a40 to 8bcbc6f Compare September 8, 2016 01:26
@cyli
Copy link
Contributor Author

cyli commented Sep 8, 2016

Just to make sure I remembered correctly - did we want the secrets in a different RPC service entirely, because the control one was too big? Or did we want it in the same RPC service but a different file? cc @stevvooe


// GetSecretRequest is the request to get a `Secret` object given a secret name.
message GetSecretRequest {
string name = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most objects are fetched by id, rather than name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured you'd want to look up a secret by name vs ID - I guess they should use ListSecret for that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, you list by name, then use the id to access it via get.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, you list by name, then use the id to access it via get.

Agreed, this is how it works with other objects in controlapi.

@stevvooe
Copy link
Contributor

stevvooe commented Sep 8, 2016

@cyli The structure and file layout of this PR looks optimal.

We may want to discuss with @al but since secrets aren't necessarily a cluster only operation, this will allow us to relocate the component running the actual service. Effectively, we could decouple this from the cluster types, if need be.

@al
Copy link

al commented Sep 8, 2016

Not the right @al I'm afraid. Who is this guy? He seems to be rather
prolific. I almost wish I was he.

On 8 Sep 2016 20:23, "Stephen Day" notifications@github.com wrote:

@cyli https://github.com/cyli The structure and file layout of this PR
looks optimal.

We may want to discuss with @al https://github.com/al but since secrets
aren't necessarily a cluster only operation, this will allow us to relocate
the component running the actual service. Effectively, we could decouple
this from the cluster types, if need be.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#1511 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAApv97Tp-r9Mb-j6PpcHIISy3mk5gS3ks5qoGC-gaJpZM4J3dfm
.

@stevvooe
Copy link
Contributor

stevvooe commented Sep 8, 2016

@al My bad. Hah.

PTAL @aluzzardi

// SecretType provides information about what kind of secret this is
enum SecretType {
CONTAINER = 0 [(gogoproto.enumvalue_customname) = "ContainerSecret"];
NODE = 1 [(gogoproto.enumvalue_customname) = "NodeSecret"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cyli let's remove node for now

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diogomonica For the network encryption key we decided to add a new secret type. Should we add a type 'NETWORK' to SecretType ? What is its intended purpose, is it for type checking ? ie: a SecretReference from a Service has to be a secret of type CONTAINER ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add the network specific functionality in a future PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diogomonica We need to think about this use cases now.

We need to cover the registry auth case, as well.

@cyli cyli force-pushed the secret-protos branch 2 times, most recently from 5a73a31 to 6ec5865 Compare September 8, 2016 23:37
@aaronlehmann
Copy link
Collaborator

Thanks for the really quick turnaround!

Left the global secret lamport clock because since users have to version their own via name, it'd be nice to have a reliable ordering when they list

I know I was the one who asked for this, but I feel it may not be worth the complexity anymore now that there's no internal need for it. For user display purposes, I think ordering by timestamp would work well enough.


// SecretReference is the linkage between a service and a secret that it uses.
message SecretReference {
// Name is the name of the secret that this references.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, this name will be informational, and secret_id below will be used to actually resolve the secret. Let's make this clear in the comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I've also moved this to the end of the message (although I don't know that ordering implies any sort of importance).

@sanimej
Copy link
Contributor

sanimej commented Sep 23, 2016

@cyli @aaronlehmann Did we decide to drop the lamport_time field ? For network gossip encryption we need a reliable ordering to delete the old key and insert the new key on every rotation. It can be handled in the client side by having a lamport_time for each secret reference. But if its part of the Secret it will be convenient.

@cyli
Copy link
Contributor Author

cyli commented Sep 23, 2016

@sanimej I've dropped it as per @aaronlehmann's suggestion, but I can also easily add it back if it's needed.

@aaronlehmann
Copy link
Collaborator

How are network gossip keys going to be managed in a world where we have immutable secrets and no built-in versioning?

@sanimej
Copy link
Contributor

sanimej commented Sep 23, 2016

How are network gossip keys going to be managed in a world where we have immutable secrets and no built-in versioning?

For each network we will have a SecretSpec and three SecretReference in the Network object corresponding to three keys needed for gossip encryption. Network key manager in the swarm leader will be responsible for deleting the old secret, create a new one on each rotation and update the reference in the Network object. Having a lamport_time will avoid having to maintain extra state in the client (key manager in this case).

Updated network object will be sent in the Assignment stream only to the nodes that have task with that network attachment.

// removes all versions of the secret.
message RemoveSecretRequest {
string secret_id = 1 [(gogoproto.customname) = "SecretID"];
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this a repeated field ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no objection, but none of the other remove requests work this way, so would like further input from @aaronlehmann or @stevvooe or @aluzzardi :)

Copy link
Contributor Author

@cyli cyli Sep 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, to clarify this statement I think supporting removing multiple objects in a single transaction might make sense, especially since the network secrets come bundled together. However, it would be an inconsistency in what the Remove* argument takes.

I think it wouldn't be too hard to support this for other objects in the control API as well on the server side, but migrating their existing APIs over to support that may be tricky, if previously it took a single string and now it takes a list of strings.

Will the network manager actually be using the control API, or will it be updating the secret store behind the scenes? There is also an internal bool on the Secret object, which the control API does not provide any way to set - I think the assumption was that the network manager would create that Secret itself and store it?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's behind the scenes, so it can use a transaction.

I think having RemoveSecret remove a single secret is most consistent with the other external APIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Leaving this as is, then, and have also removed the max number of secrets in the cluster.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - consistency first.

It makes sense, but if we want to do it, we should do it across the board on every other Remove* request so it's outside of the scope of this PR.

@aaronlehmann
Copy link
Collaborator

Thanks for explaining.

I think it may be preferable to keep the state in the key manager, versus maintaining the lamport_time field.

The reason is that lamport_time is inefficient to maintain. It involves listing all secrets every time a new secret is created, or maintaining state somewhere else to keep track of this. I expect the key manager would have less overhead because it doesn't need to maintain a global ordering of all secrets (maybe it could just keep the SecretsReferences sorted inside the Network object)?

@sanimej
Copy link
Contributor

sanimej commented Sep 23, 2016

I think it may be preferable to keep the state in the key manager, versus maintaining the lamport_time field.

If we don't foresee other users/clients of the secret infra having a similar requirement I think its ok to leave the versioning part to the key manager.

@@ -658,6 +658,7 @@ message RaftConfig {
uint32 election_tick = 5;
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space. ಠ_ಠ

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed


// Name is the name of the secret that this references, but this is just provided for
// lookup/display purposes. The secret in the reference will be identified by its ID.
string name = 4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SecretName?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@stevvooe
Copy link
Contributor

LGTM

// removes all versions of the secret.
message RemoveSecretRequest {
string secret_id = 1 [(gogoproto.customname) = "SecretID"];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - consistency first.

It makes sense, but if we want to do it, we should do it across the board on every other Remove* request so it's outside of the scope of this PR.

Annotations annotations = 1 [(gogoproto.nullable) = false];

// Secret payload.
bytes data = 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: naming? Not opposed to data but wondering if someone has a better name in mind (@stevvooe ?)

nit: Add a comment to data to explain the maximum allowed length

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is as good as anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data it is - discard that comment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Included a max size constant in the secrets.go control API stub, and added a comment here.

diogomonica and others added 9 commits September 23, 2016 15:54
Add a Secret top-level object type. Add a SecretReference that allows a
service to reference the secrets it needs.

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Signed-off-by: Diogo Monica <diogo.monica@gmail.com>
Signed-off-by: Diogo Monica <diogo.monica@gmail.com>
…ipulating secrets.

Also update some of the object protos to make things easier to look up.

Signed-off-by: cyli <cyli@twistedmatrix.com>
Signed-off-by: cyli <cyli@twistedmatrix.com>
…ets and max number of secret versions.

Also add dispatcher protos for secrets.

Signed-off-by: cyli <cyli@twistedmatrix.com>
Signed-off-by: cyli <cyli@twistedmatrix.com>
Signed-off-by: cyli <cyli@twistedmatrix.com>
…terface

Signed-off-by: cyli <cyli@twistedmatrix.com>
@diogomonica diogomonica merged commit 63600e0 into moby:master Sep 23, 2016
@cyli cyli deleted the secret-protos branch September 23, 2016 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants