Rename project to namespace and reference #1114.

This commit is contained in:
Eric Tune 2014-09-05 13:59:15 -07:00
parent 371e7020b5
commit 57ca9eefc8
2 changed files with 219 additions and 42 deletions

View File

@ -111,8 +111,8 @@ the authentication details are unknown to K8s.
Initial Features: Initial Features:
- there is no superuser `userAccount` - there is no superuser `userAccount`
- `userAccount` objects are statically populated in the K8s API store by reading a config file. Only a K8s Cluster Admin can do this. - `userAccount` objects are statically populated in the K8s API store by reading a config file. Only a K8s Cluster Admin can do this.
- `userAccount` can have a default `project`. If API call does not specify a `project`, the default `project` for that caller is assumed. - `userAccount` can have a default `namespace`. If API call does not specify a `namespace`, the default `namespace` for that caller is assumed.
- `userAccount` is global. A single human with access to multiple projects is recommended to only have one userAccount. - `userAccount` is global. A single human with access to multiple namespaces is recommended to only have one userAccount.
Improvements: Improvements:
- Make `userAccount` part of a separate API group from core K8s objects like `pod`. Facilitates plugging in alternate Access Management. - Make `userAccount` part of a separate API group from core K8s objects like `pod`. Facilitates plugging in alternate Access Management.
@ -138,51 +138,29 @@ Improvements:
- requires docker to integrate user namespace support, and deciding what getpwnam() does for these uids. - requires docker to integrate user namespace support, and deciding what getpwnam() does for these uids.
- any features that help users avoid use of privileged containers (https://github.com/GoogleCloudPlatform/kubernetes/issues/391) - any features that help users avoid use of privileged containers (https://github.com/GoogleCloudPlatform/kubernetes/issues/391)
###project ###Namespaces
K8s will have a have a `project` API object. K8s will have a have a `namespace` API object. It is similar to a Google Compute Engine `project`. It provides a namespace for objects created by a group of people co-operating together, preventing name collisions with non-cooperating groups. It also serves as a reference point for authorization policies.
Initial Features: Namespaces are described in [namespace.md](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/namespaces.md),
- `project` object is immutable. or will be once [#1114](https://github.com/GoogleCloudPlatform/kubernetes/pull/1114) is merged.
- `project` objects are statically populated in the K8s API store by reading a config file. Only a K8s Cluster Admin can do this.
- In order to allow using `project` name as namespace for objects under that `project`, and to ensure the compound names are still DNS-compatible names, `project` names must be DNS label format.
Improvements:
- have API calls to create and delete `project` objects.
Most API objects have an associated `project`:
- pods have a `project`.
- `project`s don't have a `project`, nor do `userAccount`s
- or else they belong to a special global `project`?
- An object's `project` cannot be changed after creation.
In the Enterprise Profile: In the Enterprise Profile:
- a `userAccount` may have permission to access several `project`s. API calls need to specify a `project`. Client libs may fill this in using a stored preference. - a `userAccount` may have permission to access several `namespace`s.
In the Simple Profile: In the Simple Profile:
- There is a single default `project`. No need to specify `project` when making an API call. - There is a single `namespace` used by the single user.
Project versus userAccount vs Labels: Namespaces versus userAccount vs Labels:
- `userAccount`s are intended for audit logging (both name and UID should be logged), and to define who has access to `project`s. - `userAccount`s are intended for audit logging (both name and UID should be logged), and to define who has access to `namespace`s.
- `labels` (see docs/labels.md) should be used to distinguish pods, users, and other objects that cooperate towards a common goal but are different in some way, such as version, or responsibilities. - `labels` (see docs/labels.md) should be used to distinguish pods, users, and other objects that cooperate towards a common goal but are different in some way, such as version, or responsibilities.
- `project`s provide a namespace for objects. - `namespace`s prevent name collisions between uncoordinated groups of people, and provide a place to attach common policies for co-operating groups of people.
*To Be Determined*
How is project selected when making a REST call?
- subdomain, e.g. http://myproject.kubernetes.example.com
- In hosted environment, may need to avoid profane or vanity names.
- Requires that the apiservers be tied into DNS, which is onerous to configure in some environments. Nice in some contexts.
- query parameter
- e.g. `/pods/<name>?project=<projectid>`
- tedious to add to every request, but necessary to disambiguate object names
- project in resource name
- e.g. `/projects/<id>/<kubernetes api>`
## Authentication ## Authentication
Goals for K8s authentication: Goals for K8s authentication:
- Include a built-in authentication system with no configuration required to use in single-user mode, and little configuration required to add several user accounts, and no https proxy required. - Include a built-in authentication system with no configuration required to use in single-user mode, and little configuration required to add several user accounts, and no https proxy required.
- Allow for authentication to be handled by a system external to Kubernetes, to allow integration with existing to enterprise authorization systems. The kubernetes project itself should avoid taking contributions of multiple authorization schemes. Instead, a trusted proxy in front of the apiserver can be used to authenticate users. - Allow for authentication to be handled by a system external to Kubernetes, to allow integration with existing to enterprise authorization systems. The kubernetes namespace itself should avoid taking contributions of multiple authorization schemes. Instead, a trusted proxy in front of the apiserver can be used to authenticate users.
- For organizations whose security requirements only allow FIPS compliant implementations (e.g. apache) for authentication. - For organizations whose security requirements only allow FIPS compliant implementations (e.g. apache) for authentication.
- So the proxy can terminate SSL, and isolate the CA-signed certificate from less trusted, higher-touch APIserver. - So the proxy can terminate SSL, and isolate the CA-signed certificate from less trusted, higher-touch APIserver.
- For organizations that already have existing SaaS web services (e.g. storage, VMs) and want a common authentication portal. - For organizations that already have existing SaaS web services (e.g. storage, VMs) and want a common authentication portal.
@ -230,30 +208,31 @@ Authorization policy is set by creating a set of Policy objects.
The API Server will be the Enforcement Point for Policy. For each API call that it receives, it will construct the Attributes needed to evaluate the policy (what user is making the call, what resource they are accessing, what they are trying to do that resource, etc) and pass those attribytes to a Decision Point. The Decision Point code evaluates the Attributes against all the Policies and allows or denys the API call. The system will be modular enough that the Decision Point code can either be linked into the APIserver binary, or be another service that the apiserver calls for each Decision (with appropriate time-limited caching as needed for performance). The API Server will be the Enforcement Point for Policy. For each API call that it receives, it will construct the Attributes needed to evaluate the policy (what user is making the call, what resource they are accessing, what they are trying to do that resource, etc) and pass those attribytes to a Decision Point. The Decision Point code evaluates the Attributes against all the Policies and allows or denys the API call. The system will be modular enough that the Decision Point code can either be linked into the APIserver binary, or be another service that the apiserver calls for each Decision (with appropriate time-limited caching as needed for performance).
Policy objects may be applicable only to a single project; K8s Project Admins would be able to create those as needed. Other Policy objects may be applicable to all projects; a K8s Cluster Admin might create those in order to authorize a new type of controller to be used by all projects, or to make a K8s User into a K8s Project Admin.) Policy objects may be applicable only to a single namespace or to all namespaces; K8s Project Admins would be able to create those as needed. Other Policy objects may be applicable to all namespaces; a K8s Cluster Admin might create those in order to authorize a new type of controller to be used by all namespaces, or to make a K8s User into a K8s Project Admin.)
## Accounting ## Accounting
The API should have a `quota` concept (see (https://github.com/GoogleCloudPlatform/kubernetes/issues/442 The API should have a `quota` concept (see (https://github.com/GoogleCloudPlatform/kubernetes/issues/442
). A quota object relates a project (and optionally a label selector) to a maximum quantity of resources that may be used (see resources.md). ). A quota object relates a namespace (and optionally a label selector) to a maximum quantity of resources that may be used (see resources.md).
Initially: Initially:
- a `quota` object is immutable. - a `quota` object is immutable.
- for hosted K8s systems that do billing, Project is recommended level for billing accounts. - for hosted K8s systems that do billing, Project is recommended level for billing accounts.
- Every object that consumes resources should have a `project` so that Resource usage stats are roll-up-able to `project`. - Every object that consumes resources should have a `namespace` so that Resource usage stats are roll-up-able to `namespace`.
- K8s Cluster Admin sets quota objects by writing a config file. - K8s Cluster Admin sets quota objects by writing a config file.
Improvements: Improvements:
- allow one project to charge the quota for one or more other projects. This would be controlled by a policy which allows changing a billing_project= label on an object. - allow one namespace to charge the quota for one or more other namespaces. This would be controlled by a policy which allows changing a billing_namespace= label on an object.
- allow quota to be set by project owners for (project x label) combinations (e.g. let "webserver" project use 100 cores, but to prevent accidents, don't allow "webserver" project and "instance=test" use more than 10 cores. - allow quota to be set by namespace owners for (namespace x label) combinations (e.g. let "webserver" namespace use 100 cores, but to prevent accidents, don't allow "webserver" namespace and "instance=test" use more than 10 cores.
- tools to help write consistent quota config files based on number of minions, historical project usages, QoS needs, etc. - tools to help write consistent quota config files based on number of minions, historical namespace usages, QoS needs, etc.
- way for K8s Cluster Admin to incrementally adjust Quota objects. - way for K8s Cluster Admin to incrementally adjust Quota objects.
Simple profile: Simple profile:
- a single `project` with infinite resource limits. - a single `namespace` with infinite resource limits.
Enterprise profile: Enterprise profile:
- multiple projects - multiple namespaces each with their own limits.
Issues: Issues:
- need for locking or "eventual consistency" when multiple apiserver goroutines are accessing the object store and handling pod creations. - need for locking or "eventual consistency" when multiple apiserver goroutines are accessing the object store and handling pod creations.

198
docs/authorization.md Normal file
View File

@ -0,0 +1,198 @@
Policies should be able to constriain on kind of object.
more about the context for a policy eval call.
predefined labels in the selector or other policy language primitive for object type (spoons moving away from labelselector such as VanillaST (gmail syntax).
namespace for attributes.
namespace for other modules?
### Policy objects
Policy objects are API objects. They express http://en.wikipedia.org/wiki/Attribute_Based_Access_Control
Simple Profile:
- one Policy object that allows the single `userAccount` to CRUD objects in the single `project`.
Enterprise Profile:
- Many policy objects in each of many projects.
- Tools and services that wrap policy creation interface to enforce meta policies, do template expansions, report, etc.
Initial Features:
- Policy object is immutable
- Policy objects are statically populated in the K8s API store by reading a config file. Only a K8s Cluster Admin can do this.
- Just a few policies per `project` which list which users can create objects, which can just view, them, etc.
- Objects are created with reference to these default policies.
Improvements:
- Have API calls to create and delete and modify Policy objects. These would be in a separate API group from core K8s APIs. This allows for replacing the K8s authorization service with an alternate implementation, and to centralize policies that might apply to services other than K8s.
- Ability to change policy for an object.
- Ability to create an object with a non-default policy effective immediately at creation time.
- Ability to defer policy object checking to a policy server.
- Authorization tokens to authorize entities without a `userAccount`.
### Policy object format
Policy Object:
```go
type policies map[string]policy
type policy {
project string, // ref to project of this Policy, to namespace the name.
name string, // name within the project name of the Policy
a PolicyType,
s Subject,
v Verb,
o Object
expires string // RFC3339
}
type PolicyType string
const {
ALLOW PolicyType = "ALLOW",
// Later DENY, etc.
}
type Subject string // Serialized label selector
type Verb string
const {
GET Verb = "GET",
// ... other HTTP methods.
ANY Verb = "ANY" // any http method
CREATE Verb = "CREATE" // PUT or POST
// ...
}
type Object {
exact string // any resource with exactly this path
// OR
prefix string // any resource with this path prefix (after removing "/api/<version>/")
// OR
where string // serialized label selector.
}
```
Ideally, lists of policy objects would have relatively concise and readable YAML forms, such as:
```
{name: bob_can_read_pods, a: ALLOW, s: user.name is bob@example.com, v: GET, prefix: /pods}
{name: admins_can_delete_pods, a: ALLOW, s: user.role is admin, v: DELETE, prefix: /pods}
{name: tmp1234, a: ALLOW, s: user.name is "some.agent", v: POST, prefix: /pods/somepod, expires: 2014-08-13 16:21:42-07:00 }
```
Requests that don't match at least one ALLOW are not allowed.
TODO: define DENY, and other operations and their precedence.
Delegation can be implemented by writing new narrowly tailored policies.
TODO: example of policy to delegate pod creation from a podTemplate (see https://github.com/GoogleCloudPlatform/kubernetes/issues/170).
### Architecture for Authorization
When the APIserver receives a new request, it passes the
the `userAccount`, http method, and http path to an `Authorize() method`.
In a simple implementation, the Authorize() module:
- runs in the APIserver
- searches all policy objects for a match.
- updates its cache when new Policy is added.
In alternate implementations, it may:
- have indexes to speed matching. (Maybe this can share code with Label Queries.)
- defer to a centralized auth server for the enterprise.
### Labels
Initially, IIUC, labels are strings and not API objects in their own right.
Eventually, labels may have policies or namespaces which restrict application of certain labels.
### Use cases:
only allow this pod to be started as this role if it was from a trusted build process.
Seems easy enough to add with labels and centralized policy store.
Seems like a PITA to implement and understand with three-legged oauth flow.
flows for adding three users
policy is immutible how to add subject.
inherit vs override
Make users have one of (admin, edit, view)
i
- Allow cluster admin power to create or remove any object.
- Allow project admin power to create or remove any object in the project
- Allow project admin power to add or edit any policies scoped to that project
-Create users with the 3 key roles (simulate RBAC)
- View capabilities by user
- View allowed actions by object
- control who has restart capability on a pod.
8. Can we define a Policy Template as a global resource? Can we associate a Policy Template(s) with a Project Template to make initial setup easier?
9. A policy object should have timestamps.
Typical scenario:
I have a global administrator for my OpenShift deployment that needs to access each Project.
Each project is managed by a team where each member may have particular roles with varying rights.
System view:
We have a Policy object that denotes global admin access added to each Project.
Policy{
project: "the project",
name:"openshift_admin",
prefix: "/",
s:"group=openshift_admin"
v: "ANY"
o: {
prefix: "/"
}
}
Option 1:
For each unique role, we would need to have a Policy object, but in this case our Policy subject would need to use an OR in the label selector that enumerated each person or group. This could get awkward to manage. If a policy object has timestamps, harder to reconcile when a person was added or removed from the project from this model.
Option 2:
For each person or group, we have a dedicated Policy object. Simpler to enumerate, more resources to compare potentially. Easier to audit when a person was added or removed from data model.
Issues:
There is a note that "Policy object is immutable, and is statically populated by admin"
It sounds like there is a need for a policy template, but don't you need to edit a policy in order to modify subjects to grow access?
### Blah blah blah
Have Account concept?
Cross-project permissions?
Per-api-group Actions
which are initially defined.
plugins can register their own actions.
Amazon:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::example_bucket"
}]
}
http://docs.aws.amazon.com/IAM/latest/UserGuide/PoliciesOverview.html
User creation after cluster exists:
create user object
create userCredentials and attach to user.
add labels to user or put in groups.
### Blah
What is plan for verbs per resource type?
Seems like Client already defines these.
No-one can do anything that is not allowed.
### AWS CloudFormation
wget https://raw.githubusercontent.com/marceldegraaf/blog-coreos-1/master/stack.yml
ruby -r json -r yaml -e "yaml = YAML.load(File.read('./stack.yml')); print yaml.to_json" > stack.json
Check it out.
Check out how.
### Concepts:
Enforcement point (reads a API call, adds attributes, and calls Decision Point)
Attribute Sources (adds attributes)
Decision Piont (evals policies)