github.com/argoproj/argo-cd/v2@v2.10.9/docs/developer-guide/extensions/proxy-extensions.md (about) 1 # Proxy Extensions 2 *Current Status: [Alpha][1] (Since v2.7.0)* 3 4 ## Overview 5 6 With UI extensions it is possible to enhance Argo CD web interface to 7 provide valuable data to the user. However the data is restricted to 8 the resources that belongs to the Application. With proxy extensions 9 it is also possible to add additional functionality that have access 10 to data provided by backend services. In this case Argo CD API server 11 acts as a reverse-proxy authenticating and authorizing incoming 12 requests before forwarding to the backend service. 13 14 ## Configuration 15 16 As proxy extension is in [Alpha][1] phase, the feature is disabled by 17 default. To enable it, it is necessary to configure the feature flag 18 in Argo CD command parameters. The easiest way to to properly enable 19 this feature flag is by adding the `server.enable.proxy.extension` key 20 in the existing `argocd-cmd-params-cm`. For example: 21 22 ```yaml 23 apiVersion: v1 24 kind: ConfigMap 25 metadata: 26 name: argocd-cmd-params-cm 27 namespace: argocd 28 data: 29 server.enable.proxy.extension: "true" 30 ``` 31 32 Once the proxy extension is enabled, it can be configured in the main 33 Argo CD configmap ([argocd-cm][2]). 34 35 The example below demonstrates all possible configurations available 36 for proxy extensions: 37 38 ```yaml 39 apiVersion: v1 40 kind: ConfigMap 41 metadata: 42 name: argocd-cm 43 namespace: argocd 44 data: 45 extension.config: | 46 extensions: 47 - name: httpbin 48 backend: 49 connectionTimeout: 2s 50 keepAlive: 15s 51 idleConnectionTimeout: 60s 52 maxIdleConnections: 30 53 services: 54 - url: http://httpbin.org 55 headers: 56 - name: some-header 57 value: '$some.argocd.secret.key' 58 cluster: 59 name: some-cluster 60 server: https://some-cluster 61 ``` 62 63 Note: There is no need to restart Argo CD Server after modifiying the 64 `extension.config` entry in Argo CD configmap. Changes will be 65 automatically applied. A new proxy registry will be built making 66 all new incoming extensions requests (`<argocd-host>/extensions/*`) to 67 respect the new configuration. 68 69 Every configuration entry is explained below: 70 71 #### `extensions` (*list*) 72 73 Defines configurations for all extensions enabled. 74 75 #### `extensions.name` (*string*) 76 (mandatory) 77 78 Defines the endpoint that will be used to register the extension 79 route. For example, if the value of the property is `extensions.name: 80 my-extension` then the backend service will be exposed under the 81 following url: 82 83 <argocd-host>/extensions/my-extension 84 85 #### `extensions.backend.connectionTimeout` (*duration string*) 86 (optional. Default: 2s) 87 88 Is the maximum amount of time a dial to the extension server will wait 89 for a connect to complete. 90 91 #### `extensions.backend.keepAlive` (*duration string*) 92 (optional. Default: 15s) 93 94 Specifies the interval between keep-alive probes for an active network 95 connection between the API server and the extension server. 96 97 #### `extensions.backend.idleConnectionTimeout` (*duration string*) 98 (optional. Default: 60s) 99 100 Is the maximum amount of time an idle (keep-alive) connection between 101 the API server and the extension server will remain idle before 102 closing itself. 103 104 #### `extensions.backend.maxIdleConnections` (*int*) 105 (optional. Default: 30) 106 107 Controls the maximum number of idle (keep-alive) connections between 108 the API server and the extension server. 109 110 #### `extensions.backend.services` (*list*) 111 112 Defines a list with backend url by cluster. 113 114 #### `extensions.backend.services.url` (*string*) 115 (mandatory) 116 117 Is the address where the extension backend must be available. 118 119 #### `extensions.backend.services.headers` (*list*) 120 121 If provided, the headers list will be added on all outgoing requests 122 for this service config. Existing headers in the incoming request with 123 the same name will be overriden by the one in this list. Reserved header 124 names will be ignored (see the [headers](#incoming-request-headers) below). 125 126 #### `extensions.backend.services.headers.name` (*string*) 127 (mandatory) 128 129 Defines the name of the header. It is a mandatory field if a header is 130 provided. 131 132 #### `extensions.backend.services.headers.value` (*string*) 133 (mandatory) 134 135 Defines the value of the header. It is a mandatory field if a header is 136 provided. The value can be provided as verbatim or as a reference to an 137 Argo CD secret key. In order to provide it as a reference, it is 138 necessary to prefix it with a dollar sign. 139 140 Example: 141 142 value: '$some.argocd.secret.key' 143 144 In the example above, the value will be replaced with the one from 145 the argocd-secret with key 'some.argocd.secret.key'. 146 147 #### `extensions.backend.services.cluster` (*object*) 148 (optional) 149 150 If provided, and multiple services are configured, will have to match 151 the application destination name or server to have requests properly 152 forwarded to this service URL. If there are multiple backends for the 153 same extension this field is required. In this case at least one of 154 the two will be required: name or server. It is better to provide both 155 values to avoid problems with applications unable to send requests to 156 the proper backend service. If only one backend service is 157 configured, this field is ignored, and all requests are forwarded to 158 the configured one. 159 160 #### `extensions.backend.services.cluster.name` (*string*) 161 (optional) 162 163 It will be matched with the value from 164 `Application.Spec.Destination.Name` 165 166 #### `extensions.backend.services.cluster.server` (*string*) 167 (optional) 168 169 It will be matched with the value from 170 `Application.Spec.Destination.Server`. 171 172 ## Usage 173 174 Once a proxy extension is configured it will be made available under 175 the `/extensions/<extension-name>` endpoint exposed by Argo CD API 176 server. The example above will proxy requests to 177 `<apiserver-host>/extensions/httpbin/` to `http://httpbin.org`. 178 179 The diagram below illustrates an interaction possible with this 180 configuration: 181 182 ``` 183 ┌─────────────┐ 184 │ Argo CD UI │ 185 └────┬────────┘ 186 │ ▲ 187 GET <apiserver-host>/extensions/httpbin/anything │ │ 200 OK 188 + authn/authz headers │ │ 189 ▼ │ 190 ┌─────────┴────────┐ 191 │Argo CD API Server│ 192 └──────┬───────────┘ 193 │ ▲ 194 GET http://httpbin.org/anything │ │ 200 OK 195 │ │ 196 ▼ │ 197 ┌────────┴────────┐ 198 │ Backend Service │ 199 └─────────────────┘ 200 ``` 201 202 ### Incoming Request Headers 203 204 Note that Argo CD API Server requires additional HTTP headers to be 205 sent in order to enforce if the incoming request is authenticated and 206 authorized before being proxied to the backend service. The headers 207 are documented below: 208 209 #### `Cookie` 210 211 Argo CD UI keeps the authentication token stored in a cookie 212 (`argocd.token`). This value needs to be sent in the `Cookie` header 213 so the API server can validate its authenticity. 214 215 Example: 216 217 Cookie: argocd.token=eyJhbGciOiJIUzI1Ni... 218 219 The entire Argo CD cookie list can also be sent. The API server will 220 only use the `argocd.token` attribute in this case. 221 222 #### `Argocd-Application-Name` (mandatory) 223 224 This is the name of the project for the application for which the 225 extension is being invoked. The header value must follow the format: 226 `"<namespace>:<app-name>"`. 227 228 Example: 229 230 Argocd-Application-Name: namespace:app-name 231 232 #### `Argocd-Project-Name` (mandatory) 233 234 The logged in user must have access to this project in order to be 235 authorized. 236 237 Example: 238 239 Argocd-Project-Name: default 240 241 Argo CD API Server will ensure that the logged in user has the 242 permission to access the resources provided by the headers above. The 243 validation is based on pre-configured [Argo CD RBAC rules][3]. The 244 same headers are also sent to the backend service. The backend service 245 must also validate if the validated headers are compatible with the 246 rest of the incoming request. 247 248 ### Outgoing Requests Headers 249 250 Requests sent to backend services will be decorated with additional 251 headers. The outgoing request headers are documented below: 252 253 #### `Argocd-Target-Cluster-Name` 254 255 Will be populated with the value from `app.Spec.Destination.Name` if 256 it is not empty string in the application resource. 257 258 #### `Argocd-Target-Cluster-URL` 259 260 Will be populated with the value from `app.Spec.Destination.Server` if 261 it is not empty string is the Application resource. 262 263 Note that additional pre-configured headers can be added to outgoing 264 request. See [backend service headers](#extensionsbackendservicesheaders-list) 265 section for more details. 266 267 ### Multi Backend Use-Case 268 269 In some cases when Argo CD is configured to sync with multiple remote 270 clusters, there might be a need to call a specific backend service in 271 each of those clusters. The proxy-extension can be configured to 272 address this use-case by defining multiple services for the same 273 extension. Consider the following configuration as an example: 274 275 ```yaml 276 extension.config: | 277 extensions: 278 - name: some-extension 279 backend: 280 services: 281 - url: http://extension-name.com:8080 282 cluster 283 name: kubernetes.local 284 - url: https://extension-name.ppd.cluster.k8s.local:8080 285 cluster 286 server: user@ppd.cluster.k8s.local 287 ``` 288 289 In the example above, the API server will inspect the Application 290 destination to verify which URL should be used to proxy the incoming 291 request to. 292 293 ## Security 294 295 When a request to `/extensions/*` reaches the API Server, it will 296 first verify if it is authenticated with a valid token. It does so by 297 inspecting if the `Cookie` header is properly sent from Argo CD UI 298 extension. 299 300 Once the request is authenticated it is then verified if the 301 user has permission to invoke this extension. The permission is 302 enforced by Argo CD RBAC configuration. The details about how to 303 configure the RBAC for proxy-extensions can be found in the [RBAC 304 documentation][3] page. 305 306 Once the request is authenticated and authorized by the API server, it 307 is then sanitized before being sent to the backend service. The 308 request sanitization will remove sensitive information from the 309 request like the `Cookie` and `Authorization` headers. 310 311 A new `Authorization` header can be added to the outgoing request by 312 defining it as a header in the `extensions.backend.services.headers` 313 configuration. Consider the following example: 314 315 ```yaml 316 extension.config: | 317 extensions: 318 - name: some-extension 319 backend: 320 services: 321 - url: http://extension-name.com:8080 322 headers: 323 - name: Authorization 324 value: '$some-extension.authorization.header' 325 ``` 326 327 In the example above, all requests sent to 328 `http://extension-name.com:8080` will have an additional 329 `Authorization` header. The value of this header will be the one from 330 the [argocd-secret](../../operator-manual/argocd-secret-yaml.md) with 331 key `some-extension.authorization.header` 332 333 [1]: https://github.com/argoproj/argoproj/blob/master/community/feature-status.md 334 [2]: https://argo-cd.readthedocs.io/en/stable/operator-manual/argocd-cm.yaml 335 [3]: ../../operator-manual/rbac.md#the-extensions-resource