Skip to content

Commit b6625ab

Browse files
committed
add README and set 1.0 release
1 parent c8bd7c2 commit b6625ab

File tree

2 files changed

+86
-1
lines changed

2 files changed

+86
-1
lines changed

README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,86 @@
11
# oauth2-forwarder
2+
3+
This utility allows forwarding an oauth2 interactive request that is initiated inside a docker container to the browser on the docker host and then forwarding the resulting redirect back into the docker container. The net effect is that a command line tool inside the docker container can perform interactive oauth2 authentication using the browser flow on its host.
4+
5+
## Background
6+
7+
Imagine you have a command line tool that performs oauth2 interactive login. The typical flow of that application is this:
8+
9+
1. CLI tool sends an interactive login url to the browser and, simultaneously, opens up an http service to listen for the redirect response.
10+
2. The browser opens the login url and the user performs interactive authentication.
11+
3. The successful interactive authentication results in a redirect GET request being made with the new authentication code.
12+
4. The http service setup by the CLI tool receives the redirect requests, extracts the code, and uses it.
13+
14+
This, for example, is exactly how the @azure/msal-node library works if you use the `.acquireTokenInteractive()` method on a public application.
15+
16+
This flow breaks down if you try to use it inside a docker container (at least one without a GUI) because step 2 fails, i.e., there is no way for the CLI to launch the host's browser for interactive login. You could get around this by using a device flow, but (a) that's a little more cumbersome, and (b) often conditional access policies will block that flow if they are checking for device compliance.
17+
18+
If you ever tried to do this from inside a docker container managed by VS Code, you'd have seen that it magically works. This utility gives you similar functionality without needing to use VS Code.
19+
20+
This utility works by changing the flow above as follows using a client-server pair provided by the utility--called, respectively, `o2f-server` and `o2f-client`--to proxy sending the request and redirect urls back and forth between the container and host. The flow then becomes:
21+
22+
1. [container] CLI tool sends an interactive login url to the browser and, simultaneously, opens up an http service to listen for the redirect response.
23+
2. [container] `o2f-client` intercepts the request and forwards the url to `o2f-server` over a custom tcp port
24+
3. [host] `o2f-server` receives the request sends the the login url to the browser and simultaneously opens an http service to listen for the redirect response
25+
4. [host] The browser opens the login url and the user performs interactive authentication.
26+
5. [host] The successful interactive authentication results in a redirect GET request being made with the new authentication code.
27+
6. [host] The http service setup by `o2f-server` receives the redirect requests, extracts the code, and sends it back to `o2f-client` using the tcp channel opened in step 2.
28+
7. [container] `o2f-client` makes a GET requested for the redirect url it just received.
29+
8. [container] The http service setup by the CLI tool receives the redirect requests, extracts the code, and uses it.
30+
31+
## Installation and Usage
32+
33+
This helper is written in Typescript and compiles down to two Javascript scripts, one for the server and one for the client.
34+
35+
### Download
36+
37+
Download the latest release from this repo. The release consists of a filed named `oauth2-forwarder.zip` which contains two Javascript scripts: `o2f-server.js` and `o2f-client.js` plus a helper `browser.sh` script, all in a directory called `o2f`. These can be placed wherever you want, but these instructions assume they are placed in the home directories of the host and container.
38+
39+
### On the host
40+
41+
Run `node ~/of2-server.js`. This will launch the server and it will listen for TCP connections on localhost at a random port which will be displayed in the console. You will need to keep this console/terminal open.
42+
43+
Notes:
44+
45+
- You can tell it to use a specific port by setting the environmental variable `OAUTH2_FORWARDER_PORT`
46+
47+
### In the container
48+
49+
Run `export OAUTH2_FORWARDER_SERVER="host.docker.internal:PORT` where PORT is replaced with the port displayed when you ran the server.
50+
51+
Run `export BROWSER=~/o2f/browser.sh` to set an environmental variable that will intercept attemps to open the system browser. If you've moved the `o2f` directory you'll need to change this variable setting appropriately.
52+
53+
NB: This works for a linux container that uses the BROWSER variable to determine how to handle requests to open things in a browser, for example, like those created by the npm `open` library. If you have a different setup your mileage my vary. Feel free to raise an issue here to get help.
54+
55+
Run your oauth2 CLI app as normal.
56+
57+
Notes:
58+
59+
- You can turn on more verbose debugging information by setting the environmental variable `OAUTH2_FORWARDER_DEBUG` to `true`. The logging on the client side is saved in `/tmp/oauth2-forwarder.log`. On the server side it is output to the console.
60+
61+
### Using a Dockerfile
62+
63+
Here's a strategy to make this fairly easy to use with a Docker container built with a Dockerfile.
64+
65+
On the host, set a specific port that you will listen on by configuring the env variable `OAUTH2_FORWARDER_PORT`.
66+
67+
Add these lines in the Dockerfile
68+
69+
```
70+
RUN curl -LO https://github.com/sam-mfb/oauth2-forwarder/releases/download/v[VERSION]/oauth2-forwarder.zip
71+
RUN unzip oauth2-forwarder.zip
72+
ENV OAUTH2_FORWARDER_SERVER host.docker.internal:[PORT]
73+
ENV BROWSER ~/o2f/browser.sh
74+
```
75+
76+
Of course, replace `[VERSION]` and `[PORT]` with the actual version number and port number (or use Docker's `ARG` command).
77+
78+
## Debugging
79+
80+
You can enable debugging on either the server or the client by setting the environmental variable `OAUTH2_FORWARDER_DEBUG` to `true`.
81+
82+
## Security
83+
84+
Since this is using all localhost tcp communications the security model is the same using this tool as it is in the non-containerized solution. In other words, in both cases the received auth code is transmitted over plaintext tcp on the localhost only. NB: you could modify this tool to send the client<-->server traffic across the network, but that would not be a good idea.
85+
86+
NB: If you believe there is a security issue with the app, please reach out to me directly via email, which is just `sam` at my company's domain.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oauth2-forwarder",
3-
"version": "0.1.0",
3+
"version": "1.0.0",
44
"description": "utilities for forwarding oauth2 interactive flow (e.g. container to host)",
55
"main": "dist/index.js",
66
"scripts": {

0 commit comments

Comments
 (0)