Skip to content

Seamlessly add modern auth and content caching to old tools and CI

Notifications You must be signed in to change notification settings

johnterickson/devproxy

Repository files navigation

Presentation PDF

Instead of putting caching, auth, etc into every single tool, put it in a proxy and route the tools through it. See also: https://github.com/zjrunner/prism

Since we don't want just anybody to be able to route traffic through this proxy and act with your auth, we need to limit access to this proxy itself.

First, this proxy will only listen for connections coming from the local machine. This means that requests from other computers will be ignored - even if the firewall is opened.

Additionally, the proxy will require an additional level of auth to ensure that not just any random program on a computer can make requests through this proxy. Example options:

  • The connection to the proxy provides a session token as proxy basic auth.
  • The connection to the proxy can be linked back to a process tree that has a trusted root process. E.g. you start your dev environment shell and all processes launched from that shell will be able to access the proxy.

Example output of starting proxy:

For most apps:
  $env:http_proxy = "$(D:\src\DevProxy\Proxy\bin\Release\net5.0\DevProxy.exe --get_proxy)"
For windows git (via config):
  git config --add http.sslcainfo C:/Users/jerick/.devproxy/certs/root.devproxy.pem
For windows git (via env var):
  GIT_PROXY_SSL_CAINFO=C:/Users/jerick/.devproxy/certs/root.devproxy.pem
For WSL2 (Ubuntu tested):
  1. Once, install root cert
       sudo apt install ca-certificates
       sudo cp /mnt/c/Users/jerick/.devproxy/certs/root.devproxy.pem /etc/ssl/certs/devproxy.pem
       sudo update-ca-certificates --verbose --fresh | grep -i devproxy
  2. Set envvars to enable (add this to .bashrc)
       export http_proxy=$(/mnt/d/src/DevProxy/Proxy/bin/Release/net5.0/DevProxy.exe --get_wsl_proxy)
       export https_proxy=$http_proxy
       export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/devproxy.pem

Example using proxy from powershell:

  • AuthToProxyPlugins: [ProxyAuthorizationHeaderProxyAuthPlugin]
  • RequestPlugins: [AzureDevOpsAuthRequestPlugin]
PS C:\Users\jerick> $env:HTTPS_PROXY = "http://$(D:\src\DevProxy\bin\Debug\net5.0\win10-x64\publish\DevProxy.exe --get_token)@localhost:8888"
PS C:\Users\jerick> curl.exe --ssl-no-revoke https://dev.azure.com/mseng  -D headers.txt -o out.txt; findstr DevProxy headers.txt
X-DevProxy-AuthToProxy-ProxyPasswordAuthPlugin: Authenticated_UserMatch_SHA512=5034090E
X-DevProxy-AzureDevOpsAuthPlugin-TokenType: WindowsIntegratedAuth
X-DevProxy-AzureDevOpsAuthPlugin-TokenSHA512: 12C88899

Example using proxy from WSL2:

  • AuthToProxyPlugins: [ProxyAuthorizationHeaderProxyAuthPlugin]
  • RequestPlugins: [AzureDevOpsAuthRequestPlugin]
john@jerick-hpz440:~$ export HTTP_PROXY=http://$(/mnt/d/src/DevProxy/bin/Debug/net5.0/win10-x64/publish/DevProxy.exe --get_token)@172.28.160.1:8888
john@jerick-hpz440:~$ export HTTPS_PROXY=$HTTP_PROXY
john@jerick-hpz440:~$ curl https://dev.azure.com/mseng -D headers.txt -o body.txt && grep DevProxy headers.txt
X-DevProxy-AuthToProxy-ProxyPasswordAuthPlugin: Authenticated_UserMatch_SHA512=5034090E
X-DevProxy-AzureDevOpsAuthPlugin-TokenType: WindowsIntegratedAuth
X-DevProxy-AzureDevOpsAuthPlugin-TokenSHA512: F22C0ACA

Example of automatically creating minimal SAS signatures for each request (set STORAGE_CONNECTION_STRING before starting proxy):

  • AuthToProxyPlugins: [ProxyAuthorizationHeaderProxyAuthPlugin]
  • RequestPlugins: [AzureBlobSasRequestPlugin]
john@jerick-hpz440:~$ curl -v -X PUT -d "From DevProxy: Hello, Azure Storage! $(date)"$'\n' -H "x-ms-blob-type: BlockBlob" https://jerickbuildcache.blob.core.windows.net/devproxytest/hello.txt 2>&1 | grep DevProxy
*  issuer: CN=DevProxy for jerick
< X-DevProxy-AuthToProxy-ProxyAuthorizationHeaderProxyAuthPluginInstance: Authenticated_PasswordMatch_SHA512=07A6974FB90B91F566F502033A4B4BA7
< X-DevProxy-AzureBlobSasRequestPlugin-SAS: racwdxltmei_2021-10-13T20:45:44
john@jerick-hpz440:~$ curl -v https://jerickbuildcache.blob.core.windows.net/devproxytest/hello.txt 2>&1 | grep DevProxy
*  issuer: CN=DevProxy for jerick
< X-DevProxy-AuthToProxy-ProxyAuthorizationHeaderProxyAuthPluginInstance: Authenticated_PasswordMatch_SHA512=07A6974FB90B91F566F502033A4B4BA7
< X-DevProxy-AzureBlobSasRequestPlugin-SAS: r_2021-10-13T20:46:01
From DevProxy: Hello, Azure Storage! Wed Oct 13 13:40:44 PDT 2021

Example of both authenticating to Azure DevOps via AAD and then caching the download of packages:

  • AuthToProxyPlugins: [ProxyAuthorizationHeaderProxyAuthPlugin]
  • RequestPlugins: [AzureDevOpsAuthRequestPlugin,BlobStoreCacheRequestPlugin]
curl -v -L https://outlookweb.pkgs.visualstudio.com/_packaging/owa-npm/npm/registry/@fluentui/keyboard-key/-/keyboard-key-0.2.17.tgz -o keyboard.tgz
< HTTP/1.1 303 See Other
< Location: https://9bgvsblobprodeus2185.vsblob.vsassets.io/b-c8701bf2aece44c9baedcf8a12ad5bd3/60FF07D444210A44BD5062A4113A2BAFF6DEB8718C8FA82756DCF0B9A4D931F700.blob?[redacted]
< X-DevProxy-AuthToProxy-ProxyAuthorizationHeaderProxyAuthPluginInstance: Authenticated_PasswordMatch_SHA512=32A0F8A39718B9774B36A8AA6CF5D14A
< X-DevProxy-AzureDevOpsAuthRequestPlugin-TokenNotes: AAD
< X-DevProxy-AzureDevOpsAuthRequestPlugin-TokenSHA512: 7E1D09E8D6F0F9876E97424CBF2F2069
> CONNECT 9bgvsblobprodeus2185.vsblob.vsassets.io:443 HTTP/1.1
> GET /b-c8701bf2aece44c9baedcf8a12ad5bd3/60FF07D444210A44BD5062A4113A2BAFF6DEB8718C8FA82756DCF0B9A4D931F700.blob?[redacted]
< X-DevProxy-AuthToProxy-ProxyAuthorizationHeaderProxyAuthPluginInstance: Authenticated_PasswordMatch_SHA512=32A0F8A39718B9774B36A8AA6CF5D14A
< X-DevProxy-BlobStoreCacheRequestPlugin-Cache: HIT

Example using process tree to authenticate:

  • AuthToProxyPlugins: [ProcessTreeProxyAuthPlugin]
  • RequestPlugins: [AzureDevOpsAuthRequestPlugin]
echo http_proxy=%http_proxy% https_proxy=%https_proxy% && \src\DevProxy\Proxy\bin\Debug\net5.0\DevProxy.exe --run curl.exe -v --ssl-no-revoke https://dev.azure.com/mseng 2>&1 | findstr DevProxy
http_proxy=http://localhost:8888 https_proxy=http://localhost:8888
< X-DevProxy-AuthToProxy-AuthorizationHeaderProxyAuthPlugin: NoOpinion_NoHeader=Authorization
< X-DevProxy-AuthToProxy-ProxyAuthorizationHeaderProxyAuthPluginInstance: NoOpinion_NoHeader=Proxy-Authorization
< X-DevProxy-AuthToProxy-ProcessTreeProxyAuthPlugin: Authenticated_RootProcessId=21872
< X-DevProxy-AzureDevOpsAuthRequestPlugin-TokenNotes: AAD
< X-DevProxy-AzureDevOpsAuthRequestPlugin-TokenSHA512: 7E1D09E8D6F0F9876E97424CBF2F2069

Revoking all active PATs:

curl "https://vssps.dev.azure.com/mseng/_apis/tokens/pats?displayFilterOption=active&api-version=6.1-preview.1" | jq .patTokens[].authorizationId | xargs -I '{}' curl -X DELETE "https://vssps.dev.azure.com/mseng/_apis/tokens/pats?authorizationId={}&api-version=6.1-preview.1"

About

Seamlessly add modern auth and content caching to old tools and CI

Resources

Stars

Watchers

Forks

Languages