Docker’s native authorization model is a developer-friendly one, in that it enables developers to easily access any Docker command — anyone who has access to the Docker daemon has access to all the Docker commands. The same is true with third party software accessing the daemon via remote APIs. While this “batteries included” model enables easy development access and testing, enterprise-class, role-based access control had not yet been added to Docker Engine.

Our head of R&D Dima Stopel took the lead in championing this notion and starting a discussion on Github several months ago. Since then, our engineering team has been collaborating with the Docker security team and the official maintainers to develop an authorization framework –AuthZ—that will allow the implementation of fine-grained access control Docker plugins (See Docker pull request 15365).

We are pleased to announce that the AuthZ authorization Docker plugin work has been completed. AuthZ is now officially released as part of Docker 1.10. Here is the Docker release blog announcing a list of new security features in 1.10, including AuthZ.

Through our collaboration with the maintainers and Docker security team, we started work with these design principles in mind:

  • Minimal impact: We want the additional authorization logic to be added with no or very little impact to the existing Docker installations. Recompiling Docker daemon in order to incorporate authorization is not an option.
  • Flexibility: The authorization framework must support a wide variety of authorization logic and use cases. As such, the framework must be extensible.
  • Security: The authorization framework should not ask for or retain sensitive user information if at all possible. The authentication process is the place where sensitive user info such as credentials are handled, but we do not want user credentials or other potential sensitive information to be passed to the authorization process.

As many of you already know, Docker’s plugin infrastructure provides a flexible, late-bound architecture to dynamically load extensions without one having to recompile the Docker daemon. We decided to build the new authorization framework leveraging the Docker plugin architecture.

With the completion of AuthZ and the release of Docker 1.10, anyone can now create a customized third-party authorization Docker plugin and add that to their Docker daemon configuration. Subsequently, a Docker administrator can use this plugin to configure granular and custom access control policies to govern access to the various functions of the Docker daemon. The best part is you can dynamically add or modify your authorization logic without recompiling your Docker Engine.

To help you get started, we also open sourced an extensible AuthZ plugin implementation, which we’ll describe a bit more later in the post.

How does AuthZ Plugin works?

AuthZ plugins approve or deny Docker client requests to the daemon, based on both the authentication context and the command context. The authentication context should contain the user identity, the authentication method, and other context info such as location. The command context contains the relevant request data, such as the function being called, the flags passed, all the arguments in the command, and other context information such as target containers, time of the day, etc.

Note that we first need an authentication mechanism to pass the authenticated user context to AuthZ. There is a parallel effort going on for authentication plugins, AuthN, for Docker. More information on AuthN can be found here on Github (pull request 18514).

Here are a few sample access control policies that we have seen in the field (from customers that currently utilizing the access control capabilities of Twistlock’s commercial product)

  1. The “ContainerOps” group can perform “docker –run” and “docker – rm”
    {“name”:”policy_1″,”users”:[“ContainerOps”],”actions”:[“container_run”, “container_rm”]}
  2. The audit team can only perform “docker – list”, but nothing else
    {“name”:”policy_2″,”users”:[“AuditGroup”],”actions”:[“container”], “readonly”:true}
  3. Alice can run all Docker commands: {“name”:”policy_3″,”users”:[“alice”],”actions”:[“*”]}

The first states that if the user belongs in the “ConatinerOps” AD group, the user is allowed to perform “docker –run” and “docker –rm”. Otherwise the request will be denied.

The second policy states that if the authentication context stipulates that the user is in the “audit” AD group, the only requests he/she can issue against the docker daemon are read-only get operations.

Note that wildcard is supported, as illustrated by policy 3 where user “Alice” can perform any actions on docker containers.

From an architecture standpoint, when an HTTPS request is made to the Docker daemon through the CLI or via the remote API, the authorization subsystem passes the request to the installed authorization plugin(s). The request contains the user (caller) and the command context. The plugin is then responsible for deciding whether to allow or deny the request.

Note that you can create multiple plugins and chain them together in order. Each request to the daemon would pass through the chain. Only when all the plugins grant access to the resource, is the access granted.

The diagrams below depict an allow and deny authorization flow:
Docker Authz allow

Docker Authz deny

Each request sent to the plugin includes the authenticated user, the HTTP headers, and the request/response body. To enforce strict security practices, no user credentials or tokens are passed to the authorization plugins. . In addition, only those request/response bodies where the Content-Type is either text/* or application/json are sent.

During request/response processing, some authorization flows might need to do additional queries to the Docker daemon. To complete such flows, plugins can call the daemon API similar to a regular user. To enable these additional queries, the plugin must provide the means for an administrator to configure proper authentication and security policies.

More detailed information on AuthZ can be found here on Github.

How to make your own AuthZ plugins

When you create a new AuthZ plugin, you are responsible for registering your plugin as part of the Docker daemon startup.

Authorization plugins must follow the rules described in the Docker plugin API. Furthermore, the plugin must reside within the designated directory specified in the plugin directory section.

To illustrate how the AuthZ plugins work, we have created an extensible open source plugin implementation. You can download it here. The deployment instructions for the plugin can be found at the same place. The Twistlock open source AuthZ plugin is licensed under the Apache license agreement.

For more in-depth reading on AuthZ plugins, see Docker’s official Authorization plugin guidance documentation.

Summary

Advanced access control for Docker plugin has been a function within Twistlock’s commercial offerings. We are pleased to bring this to Docker’s open source code base and have it benefit a larger community of users. As a company that benefits from the open source ecosystem, we are thrilled to be able to give back to the community.

What’s Next?

← Back to All Posts Next Post →