Browse code

docs: extend: plugins: mention the sdk + systemd socket activation

Signed-off-by: Antonio Murdaca <runcom@redhat.com>

Antonio Murdaca authored on 2016/03/09 06:34:35
Showing 6 changed files
1 1
deleted file mode 100644
... ...
@@ -1,253 +0,0 @@
1
-<!--[metadata]>
2
-+++
3
-title = "Access authorization plugin"
4
-description = "How to create authorization plugins to manage access control to your Docker daemon."
5
-keywords = ["security, authorization, authentication, docker, documentation, plugin, extend"]
6
-[menu.main]
7
-parent = "engine_extend"
8
-weight = -1
9
-+++
10
-<![end-metadata]-->
11
-
12
-
13
-# Create an authorization plugin
14
-
15
-Docker's out-of-the-box authorization model is all or nothing. Any user with
16
-permission to access the Docker daemon can run any Docker client command. The
17
-same is true for callers using Docker's remote API to contact the daemon. If you
18
-require greater access control, you can create authorization plugins and add
19
-them to your Docker daemon configuration. Using an authorization plugin, a
20
-Docker administrator can configure granular access policies for managing access
21
-to Docker daemon.
22
-
23
-Anyone with the appropriate skills can develop an authorization plugin. These
24
-skills, at their most basic, are knowledge of Docker, understanding of REST, and
25
-sound programming knowledge. This document describes the architecture, state,
26
-and methods information available to an authorization plugin developer.
27
-
28
-## Basic principles
29
-
30
-Docker's [plugin infrastructure](plugin_api.md) enables
31
-extending Docker by loading, removing and communicating with
32
-third-party components using a generic API. The access authorization subsystem
33
-was built using this mechanism.
34
-
35
-Using this subsystem, you don't need to rebuild the Docker daemon to add an
36
-authorization plugin.  You can add a plugin to an installed Docker daemon. You do
37
-need to restart the Docker daemon to add a new plugin.
38
-
39
-An authorization plugin approves or denies requests to the Docker daemon based
40
-on both the current authentication context and the command context. The
41
-authentication context contains all user details and the authentication method.
42
-The command context contains all the relevant request data.
43
-
44
-Authorization plugins must follow the rules described in [Docker Plugin API](plugin_api.md).
45
-Each plugin must reside within directories described under the
46
-[Plugin discovery](plugin_api.md#plugin-discovery) section.
47
-
48
-**Note**: the abbreviations `AuthZ` and `AuthN` mean authorization and authentication
49
-respectively.
50
-
51
-## Basic architecture
52
-
53
-You are responsible for registering your plugin as part of the Docker daemon
54
-startup. You can install multiple plugins and chain them together. This chain
55
-can be ordered. Each request to the daemon passes in order through the chain.
56
-Only when all the plugins grant access to the resource, is the access granted.
57
-
58
-When an HTTP request is made to the Docker daemon through the CLI or via the
59
-remote API, the authentication subsystem passes the request to the installed
60
-authentication plugin(s). The request contains the user (caller) and command
61
-context. The plugin is responsible for deciding whether to allow or deny the
62
-request.
63
-
64
-The sequence diagrams below depict an allow and deny authorization flow:
65
-
66
-![Authorization Allow flow](images/authz_allow.png)
67
-
68
-![Authorization Deny flow](images/authz_deny.png)
69
-
70
-Each request sent to the plugin includes the authenticated user, the HTTP
71
-headers, and the request/response body. Only the user name and the
72
-authentication method used are passed to the plugin. Most importantly, no user
73
-credentials or tokens are passed. Finally, not all request/response bodies
74
-are sent to the authorization plugin. Only those request/response bodies where
75
-the `Content-Type` is either `text/*` or `application/json` are sent.
76
-
77
-For commands that can potentially hijack the HTTP connection (`HTTP
78
-Upgrade`), such as `exec`, the authorization plugin is only called for the
79
-initial HTTP requests. Once the plugin approves the command, authorization is
80
-not applied to the rest of the flow. Specifically, the streaming data is not
81
-passed to the authorization plugins. For commands that return chunked HTTP
82
-response, such as `logs` and `events`, only the HTTP request is sent to the
83
-authorization plugins.
84
-
85
-During request/response processing, some authorization flows might
86
-need to do additional queries to the Docker daemon. To complete such flows,
87
-plugins can call the daemon API similar to a regular user. To enable these
88
-additional queries, the plugin must provide the means for an administrator to
89
-configure proper authentication and security policies.
90
-
91
-## Docker client flows
92
-
93
-To enable and configure the authorization plugin, the plugin developer must
94
-support the Docker client interactions detailed in this section.
95
-
96
-### Setting up Docker daemon
97
-
98
-Enable the authorization plugin with a dedicated command line flag in the
99
-`--authorization-plugin=PLUGIN_ID` format. The flag supplies a `PLUGIN_ID`
100
-value. This value can be the plugin’s socket or a path to a specification file.
101
-
102
-```bash
103
-$ docker daemon --authorization-plugin=plugin1 --authorization-plugin=plugin2,...
104
-```
105
-
106
-Docker's authorization subsystem supports multiple `--authorization-plugin` parameters.
107
-
108
-### Calling authorized command (allow)
109
-
110
-```bash
111
-$ docker pull centos
112
-...
113
-f1b10cd84249: Pull complete
114
-...
115
-```
116
-
117
-### Calling unauthorized command (deny)
118
-
119
-```bash
120
-$ docker pull centos
121
-...
122
-docker: Error response from daemon: authorization denied by plugin PLUGIN_NAME: volumes are not allowed.
123
-```
124
-
125
-### Error from plugins
126
-
127
-```bash
128
-$ docker pull centos
129
-...
130
-docker: Error response from daemon: plugin PLUGIN_NAME failed with error: AuthZPlugin.AuthZReq: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
131
-```
132
-
133
-## API schema and implementation
134
-
135
-In addition to Docker's standard plugin registration method, each plugin
136
-should implement the following two methods:
137
-
138
-* `/AuthzPlugin.AuthZReq` This authorize request method is called before the Docker daemon processes the client request.
139
-
140
-* `/AuthzPlugin.AuthZRes` This authorize response method is called before the response is returned from Docker daemon to the client.
141
-
142
-#### /AuthzPlugin.AuthZReq
143
-
144
-**Request**:
145
-
146
-```json
147
-{
148
-    "User":              "The user identification",
149
-    "UserAuthNMethod":   "The authentication method used",
150
-    "RequestMethod":     "The HTTP method",
151
-    "RequestUri":        "The HTTP request URI",
152
-    "RequestBody":       "Byte array containing the raw HTTP request body",
153
-    "RequestHeader":     "Byte array containing the raw HTTP request header as a map[string][]string ",
154
-    "RequestStatusCode": "Request status code"
155
-}
156
-```
157
-
158
-**Response**:
159
-
160
-```json
161
-{
162
-    "Allow": "Determined whether the user is allowed or not",
163
-    "Msg":   "The authorization message",
164
-    "Err":   "The error message if things go wrong"
165
-}
166
-```
167
-#### /AuthzPlugin.AuthZRes
168
-
169
-**Request**:
170
-
171
-```json
172
-{
173
-    "User":              "The user identification",
174
-    "UserAuthNMethod":   "The authentication method used",
175
-    "RequestMethod":     "The HTTP method",
176
-    "RequestUri":        "The HTTP request URI",
177
-    "RequestBody":       "Byte array containing the raw HTTP request body",
178
-    "RequestHeader":     "Byte array containing the raw HTTP request header as a map[string][]string",
179
-    "RequestStatusCode": "Request status code",
180
-    "ResponseBody":      "Byte array containing the raw HTTP response body",
181
-    "ResponseHeader":    "Byte array containing the raw HTTP response header as a map[string][]string",
182
-    "ResponseStatusCode":"Response status code"
183
-}
184
-```
185
-
186
-**Response**:
187
-
188
-```json
189
-{
190
-   "Allow":              "Determined whether the user is allowed or not",
191
-   "Msg":                "The authorization message",
192
-   "Err":                "The error message if things go wrong",
193
-   "ModifiedBody":       "Byte array containing a modified body of the raw HTTP body (or nil if no changes required)",
194
-   "ModifiedHeader":     "Byte array containing a modified header of the HTTP response (or nil if no changes required)",
195
-   "ModifiedStatusCode": "int containing the modified version of the status code (or 0 if not change is required)"
196
-}
197
-```
198
-
199
-The modified response enables the authorization plugin to manipulate the content
200
-of the HTTP response. In case of more than one plugin, each subsequent plugin
201
-receives a response (optionally) modified by a previous plugin.
202
-
203
-### Request authorization
204
-
205
-Each plugin must support two request authorization messages formats, one from the daemon to the plugin and then from the plugin to the daemon. The tables below detail the content expected in each message.
206
-
207
-#### Daemon -> Plugin
208
-
209
-Name                   | Type              | Description
210
-User                   | string            | The user identification
211
-Authentication method  | string            | The authentication method used
212
-Request method         | enum              | The HTTP method (GET/DELETE/POST)
213
-Request URI            | string            | The HTTP request URI including API version (e.g., v.1.17/containers/json)
214
-Request headers        | map[string]string | Request headers as key value pairs (without the authorization header)
215
-Request body           | []byte            | Raw request body
216
-
217
-
218
-#### Plugin -> Daemon
219
-
220
-Name    | Type   | Description
221
-Allow   | bool   | Boolean value indicating whether the request is allowed or denied
222
-Msg     | string | Authorization message (will be returned to the client in case the access is denied)
223
-Err     | string | Error message (will be returned to the client in case the plugin encounter an error. The string value supplied may appear in logs, so should not include confidential information)
224
-
225
-### Response authorization
226
-
227
-The plugin must support two authorization messages formats, one from the daemon to the plugin and then from the plugin to the daemon. The tables below detail the content expected in each message.
228
-
229
-#### Daemon -> Plugin
230
-
231
-
232
-Name                    | Type              | Description
233
-User                    | string            | The user identification
234
-Authentication method   | string            | The authentication method used
235
-Request method          | string            | The HTTP method (GET/DELETE/POST)
236
-Request URI             | string            | The HTTP request URI including API version (e.g., v.1.17/containers/json)
237
-Request headers         | map[string]string | Request headers as key value pairs (without the authorization header)
238
-Request body            | []byte            | Raw request body
239
-Response status code    | int               | Status code from the docker daemon
240
-Response headers        | map[string]string | Response headers as key value pairs
241
-Response body           | []byte            | Raw docker daemon response body
242
-
243
-
244
-#### Plugin -> Daemon
245
-
246
-Name    | Type   | Description
247
-Allow   | bool   | Boolean value indicating whether the response is allowed or denied
248
-Msg     | string | Authorization message (will be returned to the client in case the access is denied)
249
-Err     | string | Error message (will be returned to the client in case the plugin encounter an error. The string value supplied may appear in logs, so should not include confidential information)
... ...
@@ -18,5 +18,5 @@ Currently, you can extend Docker Engine by adding a plugin. This section contain
18 18
 * [Understand Docker plugins](plugins.md)
19 19
 * [Write a volume plugin](plugins_volume.md)
20 20
 * [Write a network plugin](plugins_network.md)
21
-* [Write an authorization plugin](authorization.md)
21
+* [Write an authorization plugin](plugins_authorization.md)
22 22
 * [Docker plugin API](plugin_api.md)
... ...
@@ -96,6 +96,43 @@ directory and activates it with a handshake. See Handshake API below.
96 96
 Plugins are *not* activated automatically at Docker daemon startup. Rather,
97 97
 they are activated only lazily, or on-demand, when they are needed.
98 98
 
99
+## Systemd socket activation
100
+
101
+Plugins may also be socket activated by `systemd`. The official [Plugins helpers](https://github.com/docker/go-plugins-helpers)
102
+natively supports socket activation. In order for a plugin to be socket activated it needs
103
+a `service` file and a `socket` file.
104
+
105
+The `service` file (for example `/lib/systemd/system/your-plugin.service`):
106
+
107
+```
108
+[Unit]
109
+Description=Your plugin
110
+Before=docker.service
111
+After=network.target your-plugin.socket
112
+Requires=your-plugin.socket docker.service
113
+
114
+[Service]
115
+ExecStart=/usr/lib/docker/your-plugin
116
+
117
+[Install]
118
+WantedBy=multi-user.target
119
+```
120
+The `socket` file (for example `/lib/systemd/system/your-plugin.socket`):
121
+```
122
+[Unit]
123
+Description=Your plugin
124
+
125
+[Socket]
126
+ListenStream=/run/docker/plugins/your-plugin.sock
127
+
128
+[Install]
129
+WantedBy=sockets.target
130
+```
131
+
132
+This will allow plugins to be actually started when the Docker daemon connects to
133
+the sockets they're listening on (for instance the first time the daemon uses them
134
+or if one of the plugin goes down accidentally).
135
+
99 136
 ## API design
100 137
 
101 138
 The Plugin API is RPC-style JSON over HTTP, much like webhooks.
... ...
@@ -128,7 +165,7 @@ Responds with a list of Docker subsystems which this plugin implements.
128 128
 After activation, the plugin will then be sent events from this subsystem.
129 129
 
130 130
 Possible values are:
131
- - [`authz`](authorization.md)
131
+ - [`authz`](plugins_authorization.md)
132 132
  - [`NetworkDriver`](plugins_network.md)
133 133
  - [`VolumeDriver`](plugins_volume.md)
134 134
 
... ...
@@ -139,3 +176,8 @@ Attempts to call a method on a plugin are retried with an exponential backoff
139 139
 for up to 30 seconds. This may help when packaging plugins as containers, since
140 140
 it gives plugin containers a chance to start up before failing any user
141 141
 containers which depend on them.
142
+
143
+## Plugins helpers
144
+
145
+To ease plugins development, we're providing an `sdk` for each kind of plugins
146
+currently supported by Docker at [docker/go-plugins-helpers](https://github.com/docker/go-plugins-helpers).
142 147
new file mode 100644
... ...
@@ -0,0 +1,254 @@
0
+<!--[metadata]>
1
+title = "Access authorization plugin"
2
+description = "How to create authorization plugins to manage access control to your Docker daemon."
3
+keywords = ["security, authorization, authentication, docker, documentation, plugin, extend"]
4
+aliases = ["/engine/extend/authorization/"]
5
+[menu.main]
6
+parent = "engine_extend"
7
+weight = -1
8
+<![end-metadata]-->
9
+
10
+
11
+# Create an authorization plugin
12
+
13
+Docker's out-of-the-box authorization model is all or nothing. Any user with
14
+permission to access the Docker daemon can run any Docker client command. The
15
+same is true for callers using Docker's remote API to contact the daemon. If you
16
+require greater access control, you can create authorization plugins and add
17
+them to your Docker daemon configuration. Using an authorization plugin, a
18
+Docker administrator can configure granular access policies for managing access
19
+to Docker daemon.
20
+
21
+Anyone with the appropriate skills can develop an authorization plugin. These
22
+skills, at their most basic, are knowledge of Docker, understanding of REST, and
23
+sound programming knowledge. This document describes the architecture, state,
24
+and methods information available to an authorization plugin developer.
25
+
26
+## Basic principles
27
+
28
+Docker's [plugin infrastructure](plugin_api.md) enables
29
+extending Docker by loading, removing and communicating with
30
+third-party components using a generic API. The access authorization subsystem
31
+was built using this mechanism.
32
+
33
+Using this subsystem, you don't need to rebuild the Docker daemon to add an
34
+authorization plugin.  You can add a plugin to an installed Docker daemon. You do
35
+need to restart the Docker daemon to add a new plugin.
36
+
37
+An authorization plugin approves or denies requests to the Docker daemon based
38
+on both the current authentication context and the command context. The
39
+authentication context contains all user details and the authentication method.
40
+The command context contains all the relevant request data.
41
+
42
+Authorization plugins must follow the rules described in [Docker Plugin API](plugin_api.md).
43
+Each plugin must reside within directories described under the
44
+[Plugin discovery](plugin_api.md#plugin-discovery) section.
45
+
46
+**Note**: the abbreviations `AuthZ` and `AuthN` mean authorization and authentication
47
+respectively.
48
+
49
+## Basic architecture
50
+
51
+You are responsible for registering your plugin as part of the Docker daemon
52
+startup. You can install multiple plugins and chain them together. This chain
53
+can be ordered. Each request to the daemon passes in order through the chain.
54
+Only when all the plugins grant access to the resource, is the access granted.
55
+
56
+When an HTTP request is made to the Docker daemon through the CLI or via the
57
+remote API, the authentication subsystem passes the request to the installed
58
+authentication plugin(s). The request contains the user (caller) and command
59
+context. The plugin is responsible for deciding whether to allow or deny the
60
+request.
61
+
62
+The sequence diagrams below depict an allow and deny authorization flow:
63
+
64
+![Authorization Allow flow](images/authz_allow.png)
65
+
66
+![Authorization Deny flow](images/authz_deny.png)
67
+
68
+Each request sent to the plugin includes the authenticated user, the HTTP
69
+headers, and the request/response body. Only the user name and the
70
+authentication method used are passed to the plugin. Most importantly, no user
71
+credentials or tokens are passed. Finally, not all request/response bodies
72
+are sent to the authorization plugin. Only those request/response bodies where
73
+the `Content-Type` is either `text/*` or `application/json` are sent.
74
+
75
+For commands that can potentially hijack the HTTP connection (`HTTP
76
+Upgrade`), such as `exec`, the authorization plugin is only called for the
77
+initial HTTP requests. Once the plugin approves the command, authorization is
78
+not applied to the rest of the flow. Specifically, the streaming data is not
79
+passed to the authorization plugins. For commands that return chunked HTTP
80
+response, such as `logs` and `events`, only the HTTP request is sent to the
81
+authorization plugins.
82
+
83
+During request/response processing, some authorization flows might
84
+need to do additional queries to the Docker daemon. To complete such flows,
85
+plugins can call the daemon API similar to a regular user. To enable these
86
+additional queries, the plugin must provide the means for an administrator to
87
+configure proper authentication and security policies.
88
+
89
+## Docker client flows
90
+
91
+To enable and configure the authorization plugin, the plugin developer must
92
+support the Docker client interactions detailed in this section.
93
+
94
+### Setting up Docker daemon
95
+
96
+Enable the authorization plugin with a dedicated command line flag in the
97
+`--authorization-plugin=PLUGIN_ID` format. The flag supplies a `PLUGIN_ID`
98
+value. This value can be the plugin’s socket or a path to a specification file.
99
+
100
+```bash
101
+$ docker daemon --authorization-plugin=plugin1 --authorization-plugin=plugin2,...
102
+```
103
+
104
+Docker's authorization subsystem supports multiple `--authorization-plugin` parameters.
105
+
106
+### Calling authorized command (allow)
107
+
108
+```bash
109
+$ docker pull centos
110
+...
111
+f1b10cd84249: Pull complete
112
+...
113
+```
114
+
115
+### Calling unauthorized command (deny)
116
+
117
+```bash
118
+$ docker pull centos
119
+...
120
+docker: Error response from daemon: authorization denied by plugin PLUGIN_NAME: volumes are not allowed.
121
+```
122
+
123
+### Error from plugins
124
+
125
+```bash
126
+$ docker pull centos
127
+...
128
+docker: Error response from daemon: plugin PLUGIN_NAME failed with error: AuthZPlugin.AuthZReq: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
129
+```
130
+
131
+## API schema and implementation
132
+
133
+In addition to Docker's standard plugin registration method, each plugin
134
+should implement the following two methods:
135
+
136
+* `/AuthzPlugin.AuthZReq` This authorize request method is called before the Docker daemon processes the client request.
137
+
138
+* `/AuthzPlugin.AuthZRes` This authorize response method is called before the response is returned from Docker daemon to the client.
139
+
140
+#### /AuthzPlugin.AuthZReq
141
+
142
+**Request**:
143
+
144
+```json
145
+{
146
+    "User":              "The user identification",
147
+    "UserAuthNMethod":   "The authentication method used",
148
+    "RequestMethod":     "The HTTP method",
149
+    "RequestUri":        "The HTTP request URI",
150
+    "RequestBody":       "Byte array containing the raw HTTP request body",
151
+    "RequestHeader":     "Byte array containing the raw HTTP request header as a map[string][]string ",
152
+    "RequestStatusCode": "Request status code"
153
+}
154
+```
155
+
156
+**Response**:
157
+
158
+```json
159
+{
160
+    "Allow": "Determined whether the user is allowed or not",
161
+    "Msg":   "The authorization message",
162
+    "Err":   "The error message if things go wrong"
163
+}
164
+```
165
+#### /AuthzPlugin.AuthZRes
166
+
167
+**Request**:
168
+
169
+```json
170
+{
171
+    "User":              "The user identification",
172
+    "UserAuthNMethod":   "The authentication method used",
173
+    "RequestMethod":     "The HTTP method",
174
+    "RequestUri":        "The HTTP request URI",
175
+    "RequestBody":       "Byte array containing the raw HTTP request body",
176
+    "RequestHeader":     "Byte array containing the raw HTTP request header as a map[string][]string",
177
+    "RequestStatusCode": "Request status code",
178
+    "ResponseBody":      "Byte array containing the raw HTTP response body",
179
+    "ResponseHeader":    "Byte array containing the raw HTTP response header as a map[string][]string",
180
+    "ResponseStatusCode":"Response status code"
181
+}
182
+```
183
+
184
+**Response**:
185
+
186
+```json
187
+{
188
+   "Allow":              "Determined whether the user is allowed or not",
189
+   "Msg":                "The authorization message",
190
+   "Err":                "The error message if things go wrong",
191
+   "ModifiedBody":       "Byte array containing a modified body of the raw HTTP body (or nil if no changes required)",
192
+   "ModifiedHeader":     "Byte array containing a modified header of the HTTP response (or nil if no changes required)",
193
+   "ModifiedStatusCode": "int containing the modified version of the status code (or 0 if not change is required)"
194
+}
195
+```
196
+
197
+The modified response enables the authorization plugin to manipulate the content
198
+of the HTTP response. In case of more than one plugin, each subsequent plugin
199
+receives a response (optionally) modified by a previous plugin.
200
+
201
+### Request authorization
202
+
203
+Each plugin must support two request authorization messages formats, one from the daemon to the plugin and then from the plugin to the daemon. The tables below detail the content expected in each message.
204
+
205
+#### Daemon -> Plugin
206
+
207
+Name                   | Type              | Description
208
+-----------------------|-------------------|-------------------------------------------------------
209
+User                   | string            | The user identification
210
+Authentication method  | string            | The authentication method used
211
+Request method         | enum              | The HTTP method (GET/DELETE/POST)
212
+Request URI            | string            | The HTTP request URI including API version (e.g., v.1.17/containers/json)
213
+Request headers        | map[string]string | Request headers as key value pairs (without the authorization header)
214
+Request body           | []byte            | Raw request body
215
+
216
+
217
+#### Plugin -> Daemon
218
+
219
+Name    | Type   | Description
220
+--------|--------|----------------------------------------------------------------------------------
221
+Allow   | bool   | Boolean value indicating whether the request is allowed or denied
222
+Msg     | string | Authorization message (will be returned to the client in case the access is denied)
223
+Err     | string | Error message (will be returned to the client in case the plugin encounter an error. The string value supplied may appear in logs, so should not include confidential information)
224
+
225
+### Response authorization
226
+
227
+The plugin must support two authorization messages formats, one from the daemon to the plugin and then from the plugin to the daemon. The tables below detail the content expected in each message.
228
+
229
+#### Daemon -> Plugin
230
+
231
+
232
+Name                    | Type              | Description
233
+----------------------- |------------------ |----------------------------------------------------
234
+User                    | string            | The user identification
235
+Authentication method   | string            | The authentication method used
236
+Request method          | string            | The HTTP method (GET/DELETE/POST)
237
+Request URI             | string            | The HTTP request URI including API version (e.g., v.1.17/containers/json)
238
+Request headers         | map[string]string | Request headers as key value pairs (without the authorization header)
239
+Request body            | []byte            | Raw request body
240
+Response status code    | int               | Status code from the docker daemon
241
+Response headers        | map[string]string | Response headers as key value pairs
242
+Response body           | []byte            | Raw docker daemon response body
243
+
244
+
245
+#### Plugin -> Daemon
246
+
247
+Name    | Type   | Description
248
+--------|--------|----------------------------------------------------------------------------------
249
+Allow   | bool   | Boolean value indicating whether the response is allowed or denied
250
+Msg     | string | Authorization message (will be returned to the client in case the access is denied)
251
+Err     | string | Error message (will be returned to the client in case the plugin encounter an error. The string value supplied may appear in logs, so should not include confidential information)
... ...
@@ -644,7 +644,7 @@ multiple plugins installed, at least one must allow the request for it to
644 644
 complete.
645 645
 
646 646
 For information about how to create an authorization plugin, see [authorization
647
-plugin](../../extend/authorization.md) section in the Docker extend section of this documentation.
647
+plugin](../../extend/plugins_authorization.md) section in the Docker extend section of this documentation.
648 648
 
649 649
 
650 650
 ## Daemon user namespace options
... ...
@@ -521,7 +521,7 @@ multiple plugins installed, at least one must allow the request for it to
521 521
 complete.
522 522
 
523 523
 For information about how to create an authorization plugin, see [authorization
524
-plugin](https://docs.docker.com/engine/extend/authorization.md) section in the
524
+plugin](https://docs.docker.com/engine/extend/plugins_authorization.md) section in the
525 525
 Docker extend section of this documentation.
526 526
 
527 527