Merge branch 'master' into 14716-webdav-cluster-config
[arvados.git] / services / keep-web / doc.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 // Keep-web provides read/write HTTP (WebDAV) access to files stored
6 // in Keep. It serves public data to anonymous and unauthenticated
7 // clients, and serves private data to clients that supply Arvados API
8 // tokens. It can be installed anywhere with access to Keep services,
9 // typically behind a web proxy that supports TLS.
10 //
11 // See http://doc.arvados.org/install/install-keep-web.html.
12 //
13 // Configuration
14 //
15 // The default cluster configuration file location is
16 // /etc/arvados/config.yml.
17 //
18 // Example configuration file
19 //
20 //   Clusters:
21 //     zzzzz:
22 //       SystemRootToken: ""
23 //       Services:
24 //         Controller:
25 //           ExternalURL: "https://example.com"
26 //           Insecure: false
27 //         WebDAV:
28 //           InternalURLs:
29 //             "http://:1234/": {}
30 //         WebDAVDownload:
31 //           InternalURLs:
32 //             "http://:1234/": {}
33 //           ExternalURL: "https://download.example.com/"
34 //       Users:
35 //         AnonymousUserToken: "xxxxxxxxxxxxxxxxxxxx"
36 //       Collections:
37 //         TrustAllContent: false
38 //
39 // Starting the server
40 //
41 // Start a server using the default config file
42 // /etc/arvados/config.yml:
43 //
44 //   keep-web
45 //
46 // Start a server using the config file /path/to/config.yml:
47 //
48 //   keep-web -config /path/to/config.yml
49 //
50 // Proxy configuration
51 //
52 // Keep-web does not support TLS natively. Typically, it is installed
53 // behind a proxy like nginx.
54 //
55 // Here is an example nginx configuration.
56 //
57 //      http {
58 //        upstream keep-web {
59 //          server localhost:1234;
60 //        }
61 //        server {
62 //          listen *:443 ssl;
63 //          server_name collections.example.com *.collections.example.com ~.*--collections.example.com;
64 //          ssl_certificate /root/wildcard.example.com.crt;
65 //          ssl_certificate_key /root/wildcard.example.com.key;
66 //          location  / {
67 //            proxy_pass http://keep-web;
68 //            proxy_set_header Host $host;
69 //            proxy_set_header X-Forwarded-For $remote_addr;
70 //          }
71 //        }
72 //      }
73 //
74 // It is not necessary to run keep-web on the same host as the nginx
75 // proxy. However, TLS is not used between nginx and keep-web, so
76 // intervening networks must be secured by other means.
77 //
78 // Anonymous downloads
79 //
80 // The "Users.AnonymousUserToken" configuration entry used when
81 // when processing anonymous requests, i.e., whenever a web client
82 // does not supply its own Arvados API token via path, query string,
83 // cookie, or request header.
84 //
85 //   Clusters:
86 //     zzzzz:
87 //       Users:
88 //         AnonymousUserToken: "xxxxxxxxxxxxxxxxxxxxxxx"
89 //
90 // See http://doc.arvados.org/install/install-keep-web.html for examples.
91 //
92 // Download URLs
93 //
94 // The following "same origin" URL patterns are supported for public
95 // collections and collections shared anonymously via secret links
96 // (i.e., collections which can be served by keep-web without making
97 // use of any implicit credentials like cookies). See "Same-origin
98 // URLs" below.
99 //
100 //   http://collections.example.com/c=uuid_or_pdh/path/file.txt
101 //   http://collections.example.com/c=uuid_or_pdh/t=TOKEN/path/file.txt
102 //
103 // The following "multiple origin" URL patterns are supported for all
104 // collections:
105 //
106 //   http://uuid_or_pdh--collections.example.com/path/file.txt
107 //   http://uuid_or_pdh--collections.example.com/t=TOKEN/path/file.txt
108 //
109 // In the "multiple origin" form, the string "--" can be replaced with
110 // "." with identical results (assuming the downstream proxy is
111 // configured accordingly). These two are equivalent:
112 //
113 //   http://uuid_or_pdh--collections.example.com/path/file.txt
114 //   http://uuid_or_pdh.collections.example.com/path/file.txt
115 //
116 // The first form (with "--" instead of ".") avoids the cost and
117 // effort of deploying a wildcard TLS certificate for
118 // *.collections.example.com at sites that already have a wildcard
119 // certificate for *.example.com. The second form is likely to be
120 // easier to configure, and more efficient to run, on a downstream
121 // proxy.
122 //
123 // In all of the above forms, the "collections.example.com" part can
124 // be anything at all: keep-web itself ignores everything after the
125 // first "." or "--". (Of course, in order for clients to connect at
126 // all, DNS and any relevant proxies must be configured accordingly.)
127 //
128 // In all of the above forms, the "uuid_or_pdh" part can be either a
129 // collection UUID or a portable data hash with the "+" character
130 // optionally replaced by "-". (When "uuid_or_pdh" appears in the
131 // domain name, replacing "+" with "-" is mandatory, because "+" is
132 // not a valid character in a domain name.)
133 //
134 // In all of the above forms, a top level directory called "_" is
135 // skipped. In cases where the "path/file.txt" part might start with
136 // "t=" or "c=" or "_/", links should be constructed with a leading
137 // "_/" to ensure the top level directory is not interpreted as a
138 // token or collection ID.
139 //
140 // Assuming there is a collection with UUID
141 // zzzzz-4zz18-znfnqtbbv4spc3w and portable data hash
142 // 1f4b0bc7583c2a7f9102c395f4ffc5e3+45, the following URLs are
143 // interchangeable:
144 //
145 //   http://zzzzz-4zz18-znfnqtbbv4spc3w.collections.example.com/foo/bar.txt
146 //   http://zzzzz-4zz18-znfnqtbbv4spc3w.collections.example.com/_/foo/bar.txt
147 //   http://zzzzz-4zz18-znfnqtbbv4spc3w--collections.example.com/_/foo/bar.txt
148 //
149 // The following URLs are read-only, but otherwise interchangeable
150 // with the above:
151 //
152 //   http://1f4b0bc7583c2a7f9102c395f4ffc5e3-45--foo.example.com/foo/bar.txt
153 //   http://1f4b0bc7583c2a7f9102c395f4ffc5e3-45--.invalid/foo/bar.txt
154 //   http://collections.example.com/by_id/1f4b0bc7583c2a7f9102c395f4ffc5e3%2B45/foo/bar.txt
155 //   http://collections.example.com/by_id/zzzzz-4zz18-znfnqtbbv4spc3w/foo/bar.txt
156 //
157 // If the collection is named "MyCollection" and located in a project
158 // called "MyProject" which is in the home project of a user with
159 // username is "bob", the following read-only URL is also available
160 // when authenticating as bob:
161 //
162 //   http://collections.example.com/users/bob/MyProject/MyCollection/foo/bar.txt
163 //
164 // An additional form is supported specifically to make it more
165 // convenient to maintain support for existing Workbench download
166 // links:
167 //
168 //   http://collections.example.com/collections/download/uuid_or_pdh/TOKEN/foo/bar.txt
169 //
170 // A regular Workbench "download" link is also accepted, but
171 // credentials passed via cookie, header, etc. are ignored. Only
172 // public data can be served this way:
173 //
174 //   http://collections.example.com/collections/uuid_or_pdh/foo/bar.txt
175 //
176 // Collections can also be accessed (read-only) via "/by_id/X" where X
177 // is a UUID or portable data hash.
178 //
179 // Authorization mechanisms
180 //
181 // A token can be provided in an Authorization header:
182 //
183 //   Authorization: OAuth2 o07j4px7RlJK4CuMYp7C0LDT4CzR1J1qBE5Avo7eCcUjOTikxK
184 //
185 // A base64-encoded token can be provided in a cookie named "api_token":
186 //
187 //   Cookie: api_token=bzA3ajRweDdSbEpLNEN1TVlwN0MwTERUNEN6UjFKMXFCRTVBdm83ZUNjVWpPVGlreEs=
188 //
189 // A token can be provided in an URL-encoded query string:
190 //
191 //   GET /foo/bar.txt?api_token=o07j4px7RlJK4CuMYp7C0LDT4CzR1J1qBE5Avo7eCcUjOTikxK
192 //
193 // A suitably encoded token can be provided in a POST body if the
194 // request has a content type of application/x-www-form-urlencoded or
195 // multipart/form-data:
196 //
197 //   POST /foo/bar.txt
198 //   Content-Type: application/x-www-form-urlencoded
199 //   [...]
200 //   api_token=o07j4px7RlJK4CuMYp7C0LDT4CzR1J1qBE5Avo7eCcUjOTikxK
201 //
202 // If a token is provided in a query string or in a POST request, the
203 // response is an HTTP 303 redirect to an equivalent GET request, with
204 // the token stripped from the query string and added to a cookie
205 // instead.
206 //
207 // Indexes
208 //
209 // Keep-web returns a generic HTML index listing when a directory is
210 // requested with the GET method. It does not serve a default file
211 // like "index.html". Directory listings are also returned for WebDAV
212 // PROPFIND requests.
213 //
214 // Compatibility
215 //
216 // Client-provided authorization tokens are ignored if the client does
217 // not provide a Host header.
218 //
219 // In order to use the query string or a POST form authorization
220 // mechanisms, the client must follow 303 redirects; the client must
221 // accept cookies with a 303 response and send those cookies when
222 // performing the redirect; and either the client or an intervening
223 // proxy must resolve a relative URL ("//host/path") if given in a
224 // response Location header.
225 //
226 // Intranet mode
227 //
228 // Normally, Keep-web accepts requests for multiple collections using
229 // the same host name, provided the client's credentials are not being
230 // used. This provides insufficient XSS protection in an installation
231 // where the "anonymously accessible" data is not truly public, but
232 // merely protected by network topology.
233 //
234 // In such cases -- for example, a site which is not reachable from
235 // the internet, where some data is world-readable from Arvados's
236 // perspective but is intended to be available only to users within
237 // the local network -- the downstream proxy should configured to
238 // return 401 for all paths beginning with "/c=".
239 //
240 // Same-origin URLs
241 //
242 // Without the same-origin protection outlined above, a web page
243 // stored in collection X could execute JavaScript code that uses the
244 // current viewer's credentials to download additional data from
245 // collection Y -- data which is accessible to the current viewer, but
246 // not to the author of collection X -- from the same origin
247 // (``https://collections.example.com/'') and upload it to some other
248 // site chosen by the author of collection X.
249 //
250 // Attachment-Only host
251 //
252 // It is possible to serve untrusted content and accept user
253 // credentials at the same origin as long as the content is only
254 // downloaded, never executed by browsers. A single origin (hostname
255 // and port) can be designated as an "attachment-only" origin: cookies
256 // will be accepted and all responses will have a
257 // "Content-Disposition: attachment" header. This behavior is invoked
258 // only when the designated origin matches exactly the Host header
259 // provided by the client or downstream proxy.
260 //
261 //   Clusters:
262 //     zzzzz:
263 //       Services:
264 //         WebDAVDownload:
265 //           ExternalURL: "https://domain.example:9999"
266 //
267 // Trust All Content mode
268 //
269 // In TrustAllContent mode, Keep-web will accept credentials (API
270 // tokens) and serve any collection X at
271 // "https://collections.example.com/c=X/path/file.ext".  This is
272 // UNSAFE except in the special case where everyone who is able write
273 // ANY data to Keep, and every JavaScript and HTML file written to
274 // Keep, is also trusted to read ALL of the data in Keep.
275 //
276 // In such cases you can enable trust-all-content mode.
277 //
278 //   Clusters:
279 //     zzzzz:
280 //       Collections:
281 //         TrustAllContent: true
282 //
283 // When TrustAllContent is enabled, the only effect of the
284 // Attachment-Only host setting is to add a "Content-Disposition:
285 // attachment" header.
286 //
287 //   Clusters:
288 //     zzzzz:
289 //       Services:
290 //         WebDAVDownload:
291 //           ExternalURL: "https://domain.example:9999"
292 //       Collections:
293 //         TrustAllContent: true
294 //
295 // Depending on your site configuration, you might also want to enable
296 // the "trust all content" setting in Workbench. Normally, Workbench
297 // avoids redirecting requests to keep-web if they depend on
298 // TrustAllContent being enabled.
299 //
300 // Metrics
301 //
302 // Keep-web exposes request metrics in Prometheus text-based format at
303 // /metrics. The same information is also available as JSON at
304 // /metrics.json.
305 //
306 package main