Kubernetes Access Control with dex

9a5b28c1bf706b9138017bf0fd23ac45?s=47 Eric Chiang
April 22, 2016
7.2k

Kubernetes Access Control with dex

9a5b28c1bf706b9138017bf0fd23ac45?s=128

Eric Chiang

April 22, 2016
Tweet

Transcript

  1. Eric Chiang @erchiang | eric.chiang@coreos.com Kubernetes Access Control with dex

  2. 1. Intro to dex 2. Kubernetes authn 3. Kubernetes authz

    4. The future Today’s agenda!
  3. • Open-source https://github.com/coreos/dex • OAuth2 Identity provider • OpenID Connect

    enabled • Federated Dex
  4. • 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
  5. None
  6. Dex: OAuth2

  7. Dex: OAuth2 Application End user Provider

  8. None
  9. Dex: OAuth2 Application End user Provider

  10. Dex: OAuth2 Application End user Provider dex

  11. Dex: OpenID Connect

  12. • Not OpenID, OpenID 1.0, or OpenID 2.0 Dex: OpenID

    Connect
  13. • Not OpenID, OpenID 1.0, or OpenID 2.0 • Thin

    layer on top of OAuth2 • Almost everything is the same Dex: OpenID Connect
  14. • 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
  15. How do I use it? Dex: OpenID Connect

  16. 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
  17. 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
  18. { "access_token": "SlAV32hkKG", "token_type": "Bearer", "refresh_token": "8xLOxBtZp8", "expires_in": 3600 }

    OAuth2: Token Response
  19. { "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
  20. eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE JSON Web Token

  21. eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE { "alg": "RS256",

    "typ": "JWT" } JSON Web Token
  22. eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwi YWRtaW4iOnRydWV9.EkN- DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8j O19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGuERTqYZyuh tF39yxJPAjUESwxk2J5k_4zM3O- vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE { "sub": "1234567890",

    "name": "John Doe", "admin": true } JSON Web Token
  23. 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
  24. 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
  25. { "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
  26. How do I verify the signature? JSON Web Token: ID

    Token
  27. https://dex.example.com/.well-known/openid-configuration OpenID Connect: Discovery

  28. https://dex.example.com/.well-known/openid-configuration • Automatically discover information about the provider • Token,

    auth endpoint • Public keys OpenID Connect: Discovery
  29. Kubernetes Authn/Authz

  30. • 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
  31. • TLS • Password • Token Kubernetes Authn Plugins

  32. TLS certificates Kubernetes Authn Plugins: TLS

  33. • Password files • Keystone (openstack) Kubernetes Authn Plugins: Password

  34. • Token files • OpenID Connect Kubernetes Authn Plugins: Token

  35. • Token files • OpenID Connect ◦ Look at ID

    Token to determine who you are Kubernetes Authn Plugins: Token
  36. ./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
  37. Quick aside: Kubernetes “plugins”

  38. Dex Federation and Kubernetes

  39. Dex federation and Kubernetes

  40. Dex Federation and Kubernetes dex

  41. Dex Federation and Kubernetes dex

  42. Kubernetes Authz

  43. • AllowAll • DenyAll • ABAC File Kubernetes Authz

  44. abac.jsonl (pretty printed) { "user": "eric", "namespace": "tectonic-prod", "resource": "service"

    "readonly": true, } { "group": "tectonic", "namespace": "tectonic-dev", "resource": "*" } Kubernetes Authz: ABAC File
  45. • AllowAll • DenyAll • ABAC File Kubernetes Authz

  46. • AllowAll • DenyAll • ABAC File • Webhook Kubernetes

    Authz
  47. ./kube-apiserver \ --authorization-mode=Webhook \ --authorization-webhook-config-file=webhookconfig \ # ... Kubernetes Authz

    Plugins: Webhook
  48. ./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
  49. 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
  50. if review.user == "jane" && review.Namespace != "development" { return

    errors.New("unauthorized") } Kubernetes Authz Plugins: Webhook
  51. The Future

  52. The Future • Authn ◦ Continue to improve the login

    (kubectl login) ◦ Automatic refreshing of tokens in kubeconfig ◦ Grouping users in dex
  53. 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
  54. The Future: Authz • Webhooks are good for integrating with

    existing solutions • Kubernetes should ship with a more capable default • Upstream RBAC inspired by Openshift
  55. Thank you! Eric Chiang @erchiang | eric.chiang@coreos.com We’re hiring in

    all departments! Email: careers@coreos.com Positions: coreos.com/careers
  56. coreos.com/fest - @coreosfest May 9 & 10, 2016 - Berlin,

    Germany