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

api: add support for security profiles #1722

Closed
wants to merge 1 commit into from

Conversation

stevvooe
Copy link
Contributor

@stevvooe stevvooe commented Nov 1, 2016

We define the basis for a profile-based security dispatch. We put
forward a model, based on existing --privileged flag that can be
extended in the future to support more complex workflows.

The first aspect is to allow the container runtime to select a security
profile, keyed by name. We introduce two profiles, "default" and
"privileged" corresponding to the currently available control we have
today. We will extend this model to support more complex scenarios, with
more granular control, in the future.

We balance this model with a Node security profile ACL that can select
which profiles can be run on a node. Users can add and remove items from
this ACL to control which security levels can run on a given node. We
define the empty list to be allowing the "Default" security profile.

To support future interaction, we also define that profiles are
additive. This means that the capability of a set of profiles is a union
of all the specified profiles.

Signed-off-by: Stephen J Day stephen.day@docker.com

@mgoelzer @justincormack @icecrime @aluzzardi @crosbymichael

@justincormack
Copy link
Contributor

I don't think default should be a profile, it is a lack of a profile. We made this mistake about having meaningful defaults before. It should be fine to have nothing selected mean not privileged.

@@ -50,6 +50,16 @@ message NodeSpec {
// Availability allows a user to control the current scheduling status of a
// node.
Availability availability = 4;

// AllowedSecurityProfiles let's an operator select which security profiles
Copy link
Collaborator

Choose a reason for hiding this comment

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

lets

@codecov-io
Copy link

codecov-io commented Nov 1, 2016

Current coverage is 56.29% (diff: 100%)

Merging #1722 into master will increase coverage by 0.41%

@@             master      #1722   diff @@
==========================================
  Files            96         93     -3   
  Lines         14902      14796   -106   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           8328       8330     +2   
+ Misses         5469       5379    -90   
+ Partials       1105       1087    -18   

Sunburst

Powered by Codecov. Last update 4dfc88c...939be4d

@stevvooe
Copy link
Contributor Author

stevvooe commented Nov 1, 2016

@justincormack How do we define that minimum set? To which mistake are you referring?

@justincormack
Copy link
Contributor

For this PR you don't need to specify anything, as the options are the empty set of privileges or the set {privileged}. default does not need to exist.

The mistake was capabilities, which we added a default set which corresponds to a lot of root capabilities (even if you are not root), which you then have to drop.

@stevvooe
Copy link
Contributor Author

stevvooe commented Nov 1, 2016

@justincormack Agreed.

Let's work this out:

Container Profiles Node ACL Operation Allowed
({}) ({}) Yes
{P} ({"privileged"}) ({}) (P) ⊄ No
{P} ({"privileged"}) {P} ({"privileged"}) {P} ⊆ {P} Yes
{E} ({"example"}) {P} ({"privileged"}) (P) ⊄ (P) EP
{E} ({"example"}) {P} ({"privileged"}) (P) ⊆ (P) EP

P = privileged
E = example
∅ = default

Above, we have a table representing the requested profiles, node ACLs and the operations/equality to calculate whether a profile may run on a given node. We evaluate both with and without privileged, showing that the container profile must be a subset of the Node ACL to progress. We then have third profile, of unknown contents. We evaluate in conditions when the E is both a subset of P and when it is not.

@crosbymichael
Copy link
Contributor

@justincormack how do you want to represent the current configuration that we have today?

@stevvooe
Copy link
Contributor Author

stevvooe commented Nov 1, 2016

@crosbymichael I added the contents of the actual fields next to the set operations. Hopefully, that makes things a little more concrete.

He is saying that the "default profile", what we do today, is represented as the empty set, which is really a base set where all sets satisfy ∅ ⊆ S and S ⊆ ∅. We don't need to define it, since it is just the base runtime.

That said, to reduce permissions with this model, we do need to define operations that negate items in the base set, but I don't think that is too much of a stretch.

@justincormack
Copy link
Contributor

justincormack commented Nov 1, 2016

@crosbymichael specify them explicitly or specify them as defaults in the daemon config explicitly so that everyone gets them, but suggest people remove them from the config

@stevvooe negative capabilities dont work.

We need to move towards an empty base set, and a way users can go to it sooner.

@crosbymichael
Copy link
Contributor

Could we have the base set be nothing, no caps, no syscalls, and the "default" docker profile adds these? This way you don't have to know about what is in the base set and figureout what you have to remove/unset if you are building a new profile.

@aluzzardi
Copy link
Member

aluzzardi commented Nov 1, 2016

  • Should these be defined on the Node side or at the engine level?
  • What about cluster defaults?
  • How can this be automated (e.g. large set of nodes)?
  • Could this be provided at node join time (related to the first question of engine level as well)?
  • What about backward expectations?

/cc @icecrime @dnephin

What would custom profiles look like? In this PR we assume that the behavior is hardcoded in the profile name (e.g. "privileged" means privileged)

@stevvooe
Copy link
Contributor Author

stevvooe commented Nov 2, 2016

@justincormack With a base set, how would one remove functionality from the "Default" profile?

Should these be defined on the Node side or at the engine level?

This depends on where we enforce the policy. Typically, a node may not actually know its own policy and there are implications to trusting that node. Under this proposal, we can do a set based model enforced on the managers.

What about cluster defaults?

We can make default ACLs on the global cluster config. We may need to control how these combine with existing ACLs (are they a union or do they replace?).

How can this be automated (e.g. large set of nodes)?

Of course.

Could this be provided at node join time (related to the first question of engine level as well)?

This really depends on the trust model we have for the security profiles. If we allow nodes to declare what they are willing to run, we need to think about how that works in practice.

What about backward expectations?

For upgraded clusters, the fields are empty (config and acl), so everything just continues working. We can add --privileged to achieve feature parity, but the user will need to take action to specify nodes can run --privileged or set as a cluster default.

What would custom profiles look like? In this PR we assume that the behavior is hardcoded in the profile name (e.g. "privileged" means privileged)

As long as they can be expressed as set semantics, there are no limitations. I think there are some examples in @justincormack's proposal, but we should work some examples out to make sure everything lines up.

We define the basis for a profile-based security dispatch. We put
forward a model, based on existing `--privileged` flag that can be
extended in the future to support more complex workflows.

The first aspect is to allow the container runtime to select a security
profile, keyed by name. We introduce two profiles, "default" and
"privileged" corresponding to the currently available control we have
today. We will extend this model to support more complex scenarios, with
more granular control, in the future.

We balance this model with a Node security profile ACL that can select
which profiles can be run on a node. Users can add and remove items from
this ACL to control which security levels can run on a given node. We
define the empty list to be allowing the "Default" security profile.

To support future interaction, we also define that profiles are
additive. This means that the capability of a set of profiles is a union
of all the specified profiles.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
@stevvooe
Copy link
Contributor Author

stevvooe commented Nov 2, 2016

Updated with feedback from @aaronlehmann and added a sub-message on nodespec and containerspec.

@stevvooe
Copy link
Contributor Author

stevvooe commented Nov 8, 2016

After some discussion, the idea came up that requiring an update to every Node's ACL would be expensive. It might be better to introduce an ACL object that specifies the profiles allowed and the nodes to which it applies, such that when new nodes come on line that can have the ACL automatically apply or be matched via some mechanism, such as labeling.

@galindro
Copy link

@stevvooe is there any ETA about the merge of this PR?

@stevvooe
Copy link
Contributor Author

stevvooe commented Jan 6, 2017

@galindro There are still some details to be worked out. The base concepts are likely to be similar but their needs to be ACL aggregation to make it easier to specify what can and cannot be run on an individual node.

@marcellodesales
Copy link

@stevvooe is there an ETA for this?

@stevvooe
Copy link
Contributor Author

stevvooe commented Feb 6, 2017

@marcellodesales At this time, no.

We had discussed introducing an ACL object and moving the allowed_profiles from node to that. That would allow batch update of the configuration of a large set of nodes.

I think we may also be blocked on the details of representing a security profile.

@aluzzardi What is wrong with this proposal, other than the bulk update issue?

@galindro
Copy link

galindro commented Mar 8, 2017

@stevvooe @aluzzardi any updates?

@RRAlex
Copy link

RRAlex commented Mar 8, 2017

This PR allows ACL to be enforced/propagated per node, enabling only a subset of the security rights (Capabilities, SECCOMP, no-new-privileges, etc.).

But shouldn't this come after we actually have support for those security rights/features?

I'm thinking:
#1030
moby/moby#26849
moby/moby#25885

@stevvooe
Copy link
Contributor Author

stevvooe commented Mar 8, 2017

This PR allows ACL to be enforced/propagated per node, enabling only a subset of the security rights (Capabilities, SECCOMP, no-new-privileges, etc.).

This is a narrow interpretation of the design proposed in this PR. The goal is to span the gap of priveleged support while not just having a bool. The idea would be to support richer profiles in the future based on this model.

@galindro
Copy link

@stevvooe any return about this feature? Is it almost completed or needs more discussion?

@stevvooe
Copy link
Contributor Author

@stevvooe any return about this feature? Is it almost completed or needs more discussion?

There is more discussion to be had. I am not directly working on this, but there is definitely something coming in the future. I appreciate the patience, as getting this right is very challenging.

@stevvooe
Copy link
Contributor Author

Actually, I think we can close this down in favor of moby/moby#32801.

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.

10 participants