Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Kubernetes Access Control with dex
Eric Chiang
April 22, 2016
1
7.7k
Kubernetes Access Control with dex
Eric Chiang
April 22, 2016
Tweet
Share
More Decks by Eric Chiang
See All by Eric Chiang
Securing a Kubernetes Distribution - Container Security Summit
ericchiang
0
250
KubeCon 2017: SIG auth update
ericchiang
0
210
CoreOS Fest 2017 - Containers from Scratch
ericchiang
3
720
KubeCon 2016: Kubernetes Auth and Access Control
ericchiang
3
690
Containers from Scratch
ericchiang
1
210
CoreOS Fest 2016: Kubernetes Access Control with dex
ericchiang
2
750
Featured
See All Featured
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
315
19k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
4
500
Designing Experiences People Love
moore
130
22k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_i
23
15k
The Pragmatic Product Professional
lauravandoore
19
2.9k
Art Directing for the Web. Five minutes with CSS Template Areas
malarkey
196
9.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
349
27k
What's in a price? How to price your products and services
michaelherold
229
9.4k
Design by the Numbers
sachag
271
17k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
104
16k
What's new in Ruby 2.0
geeforr
336
30k
Designing with Data
zakiwarfel
91
3.9k
Transcript
Eric Chiang @erchiang | eric.chiang@coreos.com Kubernetes Access Control with dex
1. Intro to dex 2. Kubernetes authn 3. Kubernetes authz
4. The future Today’s agenda!
• Open-source https://github.com/coreos/dex • OAuth2 Identity provider • OpenID Connect
enabled • Federated Dex
• Open-source https://github.com/coreos/dex • OAuth2 Identity provider • OpenID Connect
enabled • Federated Let the user login however the want. Provide an identity service to other applications. Dex
None
Dex: OAuth2
Dex: OAuth2 Application End user Provider
None
Dex: OAuth2 Application End user Provider
Dex: OAuth2 Application End user Provider dex
Dex: OpenID Connect
• Not OpenID, OpenID 1.0, or OpenID 2.0 Dex: OpenID
Connect
• Not OpenID, OpenID 1.0, or OpenID 2.0 • Thin
layer on top of OAuth2 • Almost everything is the same Dex: OpenID Connect
• Not OpenID, OpenID 1.0, or OpenID 2.0 • Thin
layer on top of OAuth2 • Almost everything is the same • Standardizes things left out of OAuth2 • Easier to get user info • Discovery mechanisms Dex: OpenID Connect
How do I use it? Dex: OpenID Connect
config := oauth2.Config{ ClientID: os.Getenv("client_id"), ClientSecret: os.Getenv("client_secret"), Endpoint: oauth2.Endpoint{ AuthURL:
"https://a.com/auth", TokenURL: "https://a.com/token", }, RedirectURL: "https://myapp.com/callback", Scopes: []string{"email"}, } OAuth2
config := oauth2.Config{ ClientID: os.Getenv("client_id"), ClientSecret: os.Getenv("client_secret"), Endpoint: oauth2.Endpoint{ AuthURL:
"https://a.com/auth", TokenURL: "https://a.com/token", }, RedirectURL: "https://myapp.com/callback", Scopes: []string{"email", "openid"}, } OpenID Connect
{ "access_token": "SlAV32hkKG", "token_type": "Bearer", "refresh_token": "8xLOxBtZp8", "expires_in": 3600 }
OAuth2: Token Response
{ "access_token": "SlAV32hkKG", "token_type": "Bearer", "refresh_token": "8xLOxBtZp8", "expires_in": 3600, "id_token":
"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5 NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4 XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg" } OpenID Connect: Token Response
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE JSON Web Token
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE { "alg": "RS256",
"typ": "JWT" } JSON Web Token
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE { "sub": "1234567890",
"name": "John Doe", "admin": true } JSON Web Token
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE C~ �'��cD���w�����v���s^ [7d���(��8"
��L�#;_V� ��Ɋ3K��f��c�}k��9�t���k�E:�g+��]��O5K d؞d����ﯵ�F�*8!��),�'ٓ�& =����Ȋ� JSON Web Token
Real id_token I requested from Google: eyJhbGciOiJSUzI1NiIsImtpZCI6IjQ5YWY5N2RmMmQ5MzY0MDJjN2Y1MzM4ZjM2MGQxMWFhYzJlZT JjM2QifQ. eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdF9oYXNoIjoiazRicDVjN1dHSU ZTSHp0QUJUcFloZyIsImF1ZCI6IjgxMjg3NTY3MTU0My1wZWpocGJwMjNiN3FtN241MmplMXY5amJn
ZDFvN2VoOC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwNTE4MTcxOTk4MTY0MD E1NjU2NyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhenAiOiI4MTI4NzU2NzE1NDMtcGVqaHBicDIz YjdxbTduNTJqZTF2OWpiZ2QxbzdlaDguYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJoZCI6Im NvcmVvcy5jb20iLCJlbWFpbCI6ImVyaWMuY2hpYW5nQGNvcmVvcy5jb20iLCJpYXQiOjE0NjAwNjk1 MDAsImV4cCI6MTQ2MDA3MzEwMCwibmFtZSI6IkVyaWMgQ2hpYW5nIiwiZ2l2ZW5fbmFtZSI6IkVyaW MiLCJmYW1pbHlfbmFtZSI6IkNoaWFuZyIsImxvY2FsZSI6ImVuIn0. oGKiYmScs9iaj7AnDJgBY30VyJK- NSSSfSnwdfohCcEsO6ixCfdWOXQ7ulmbUkHu45PXrgahthbIgFpFw60W7nALT8k75ubV2VheJeRvlR icZ8ct_eaAC4wLvRAxdJZBlyiFjzqBeTdapP8jCgztHPbDOXMtdMfYxIFp1pnykbFawH_wnPpKDU8n 8MmHw109j8hTcx1MArRVS8Ikq0hHHvpe462NgEvC9vn813NdqqUsERJgHyTMee5qReGaZsJQ- UtxJqfi2UGpYEog1uL5HCIDlAyGNkY2tnP0eaFmaKOnkVZWZu98OAxbEEDLPy-Rr- CofpvEjKjYtpNhuFMTQA JSON Web Token: ID Token
{ "iss": "https://accounts.google.com", "at_hash": "k4bp5c7WGIFSHztABTpYhg", "aud": "812875671543-pejhpbp23b7qm7n52je1v9jbgd1o7eh8.apps. googleusercontent.com", "sub": "105181719981640156567",
"email_verified": true, "azp": "812875671543-pejhpbp23b7qm7n52je1v9jbgd1o7eh8.apps. googleusercontent.com", "hd": "coreos.com", "email": "eric.chiang@coreos.com", "iat": 1460069500, "exp": 1460073100, "name": "Eric Chiang", "given_name": "Eric", "family_name": "Chiang", "locale": "en" } JSON Web Token: ID Token
How do I verify the signature? JSON Web Token: ID
Token
https://dex.example.com/.well-known/openid-configuration OpenID Connect: Discovery
https://dex.example.com/.well-known/openid-configuration • Automatically discover information about the provider • Token,
auth endpoint • Public keys OpenID Connect: Discovery
Kubernetes Authn/Authz
• Authentication ◦ Figuring out who you are ◦ Example:
A driver's license • Authorization ◦ Rules for who can do what ◦ Example: You must be 21 to drink Kubernetes Authn/Authz
• TLS • Password • Token Kubernetes Authn Plugins
TLS certificates Kubernetes Authn Plugins: TLS
• Password files • Keystone (openstack) Kubernetes Authn Plugins: Password
• Token files • OpenID Connect Kubernetes Authn Plugins: Token
• Token files • OpenID Connect ◦ Look at ID
Token to determine who you are Kubernetes Authn Plugins: Token
./kube-apiserver \ --oidc-issuer-url=https://dex.example.com \ --oidc-client-id=example-app \ --oidc-username-claim=email \ # ...
kubectl config set-credentials --token=$ID_TOKEN Kubernetes Authn Plugins: OIDC
Quick aside: Kubernetes “plugins”
Dex Federation and Kubernetes
Dex federation and Kubernetes
Dex Federation and Kubernetes dex
Dex Federation and Kubernetes dex
Kubernetes Authz
• AllowAll • DenyAll • ABAC File Kubernetes Authz
abac.jsonl (pretty printed) { "user": "eric", "namespace": "tectonic-prod", "resource": "service"
"readonly": true, } { "group": "tectonic", "namespace": "tectonic-dev", "resource": "*" } Kubernetes Authz: ABAC File
• AllowAll • DenyAll • ABAC File Kubernetes Authz
• AllowAll • DenyAll • ABAC File • Webhook Kubernetes
Authz
./kube-apiserver \ --authorization-mode=Webhook \ --authorization-webhook-config-file=webhookconfig \ # ... Kubernetes Authz
Plugins: Webhook
./kube-apiserver \ --authorization-mode=Webhook \ --authorization-webhook-config-file=webhookconfig \ # ... clusters: -
name: my-authz-service cluster: server: https://authz.example.com/webhook Kubernetes Authz Plugins: Webhook
POST /webhook HTTP/1.1 Host: authz.example.com { "apiVersion": "authorization.k8s.io/v1beta1", "kind": "SubjectAccessReview",
"spec": { "resourceAttributes": { "namespace": "kittensandponies", "verb": "GET", "group": "v1", "resource": "pods" }, "user": "jane" } } Kubernetes Authz Plugins: Webhook
if review.user == "jane" && review.Namespace != "development" { return
errors.New("unauthorized") } Kubernetes Authz Plugins: Webhook
The Future
The Future • Authn ◦ Continue to improve the login
(kubectl login) ◦ Automatic refreshing of tokens in kubeconfig ◦ Grouping users in dex
The Future • Authn ◦ Continue to improve the login
(kubectl login) ◦ Automatic refreshing of tokens in kubeconfig ◦ Grouping users in dex • Authz ◦ Better upstream authz solution ◦ Policies and roles
The Future: Authz • Webhooks are good for integrating with
existing solutions • Kubernetes should ship with a more capable default • Upstream RBAC inspired by Openshift
Thank you! Eric Chiang @erchiang | eric.chiang@coreos.com We’re hiring in
all departments! Email: careers@coreos.com Positions: coreos.com/careers
coreos.com/fest - @coreosfest May 9 & 10, 2016 - Berlin,
Germany