Skip to content

Commit 4f4ca34

Browse files
committed
tsidp-server.go,Makefile,server: switch to slog
Switch to slog for structured logging with appropriate log levels for activity within the app. - log all token api errors at WARN level - move tsnet.Server logging to new flag: -debug-tsnet - move request/response logging to new flag: -debug-all-requests - unify API error handling logic to writeHTTPError - switch funnel error to http.StatusUnauthorized - update docker image to use new logging flags - update README.md with new flags and env vars Signed-off-by: Benson Wong <[email protected]>
1 parent 5007403 commit 4f4ca34

File tree

15 files changed

+394
-304
lines changed

15 files changed

+394
-304
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: build build-osx build-linux test clean
1+
.PHONY: build build-osx build-linux test clean docker-image
22

33
build: build-osx build-linux
44

@@ -10,6 +10,9 @@ build-linux:
1010
@mkdir -p build
1111
GOOS=linux GOARCH=amd64 go build -o build/tsidp-server-linux-amd64-$(shell date +%Y-%m-%d)-$(shell git rev-parse --short=5 HEAD) ./tsidp-server.go
1212

13+
docker-image:
14+
docker build -t tsidp:latest .
15+
1316
test:
1417
go test -count 1 . ./server
1518

README.md

Lines changed: 93 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,49 @@
1818

1919
### (Recommended) Using the pre-built image
2020

21-
To be updated.
21+
Docker images are automatically published on when releases are tagged.
2222

23-
### Other ways to build & run tsidp
23+
```bash
24+
# to use the latest image
25+
$ docker pull ghcr.io/tailscale/tsidp:latest
2426

25-
<details>
26-
<summary>Building your own container</summary>
27+
# to use a specific release version
28+
$ docker pull ghcr.io/tailscale/tsidp:v0.0.2
29+
```
2730

28-
Replace `YOUR_TAILSCALE_AUTHKEY` with your Tailscale authentication key in the following commands:
31+
Running a tsidp container:
2932

30-
1. Use an existing auth key or create a new auth key in the [Tailscale dashboard](https://login.tailscale.com/admin/settings/keys). Ensure you select an existing [tag](https://tailscale.com/kb/1068/tags) or create a new one.
33+
> [!TIP]
34+
> Replace `YOUR_TAILSCALE_AUTHKEY` with your Tailscale authentication key in the following commands:
35+
>
36+
> Use an existing auth key or create a new auth key in the [Tailscale dashboard](https://login.tailscale.com/admin/settings/keys). Ensure you select an existing [tag](https://tailscale.com/kb/1068/tags) or create a new one.
3137
3238
```bash
33-
# Build the container using the included Dockerfile
34-
docker build -t tsidp .
35-
3639
# Run tsidp with a persistent volume to store state
3740
docker run -d \
3841
--name tsidp \
3942
-p 443:443 \
4043
-v tsidp-data:/data \
41-
-e TS_STATE_DIR=/data \
42-
-e TS_AUTHKEY=YOUR_TAILSCALE_AUTHKEY \
43-
-e TSNET_FORCE_LOGIN=1 \
4444
-e TAILSCALE_USE_WIP_CODE=1 \
45-
-e TSIDP_ENABLE_STS=1 \
45+
-e TS_STATE_DIR=/data \
4646
-e TS_HOSTNAME=idp \
47-
tsidp
47+
-e TSIDP_ENABLE_STS=1 \
48+
ghcr.io/tailscale/tsidp:latest
4849
```
4950

5051
Visit `https://idp.yourtailnet.ts.net` to confirm the service is running.
5152

52-
_If you're running tsidp for the first time, you may not be able to access it initially even though it is running. It takes a few minutes for the TLS certificate to generate._
53+
> [!NOTE]
54+
> If you're running tsidp for the first time it may take a few minutes for the TLS certificate to generate. You may not be able to access the service until the certificate is ready.
55+
56+
### Other Ways to Build and Run
57+
58+
<details>
59+
<summary>Building your own container</summary>
60+
61+
```bash
62+
$ make docker-image
63+
```
5364

5465
</details>
5566

@@ -60,26 +71,23 @@ If you'd like to build tsidp and / or run it directly you can do the following:
6071

6172
```bash
6273
# Clone the Tailscale repository
63-
git clone https://github.com/tailscale/tsidp.git
64-
cd tsidp
65-
```
66-
67-
Replace `YOUR_TAILSCALE_AUTHKEY` with your Tailscale authentication key in the following commands:
68-
69-
1. Use an existing auth key or create a new auth key in the [Tailscale dashboard](https://login.tailscale.com/admin/settings/keys). Ensure you select an existing [tag](https://tailscale.com/kb/1068/tags) or create a new one.
70-
2. Run `TS_AUTH_KEY=YOUR_TAILSCALE_AUTHKEY TAILSCALE_USE_WIP_CODE=1 TSNET_FORCE_LOGIN=1 go run .`
71-
72-
Visit `https://idp.yourtailnet.ts.net` to confirm the service is running.
74+
$ git clone https://github.com/tailscale/tsidp.git
75+
$ cd tsidp
7376

74-
_If you're running tsidp for the first time, you may not be able to access it initially even though it is running. It takes a few minutes for the TLS certificate to generate._
77+
# run with default values for flags
78+
$ TAILSCALE_USE_WIP_CODE=1 TS_AUTHKEY={YOUR_TAILSCALE_AUTHKEY} TSNET_FORCE_LOGIN=1 go run .
79+
```
7580

7681
</details>
7782

7883
## Setting an Application Capability Grant
7984

80-
tsidp requires an [Application capability grant](https://tailscale.com/kb/1537/grants-app-capabilities) to allow access to the admin UI and dynamic client registration endpoints.
85+
> [!IMPORTANT]
86+
> Access to the admin UI and dynamic client registration endpoints are **denied** by default.
87+
88+
To access the admin UI and dynamic client registration endpoints an [Application capability grant](https://tailscale.com/kb/1537/grants-app-capabilities) must be set in the the [Tailscale console](https://login.tailscale.com/admin).
8189

82-
This is a permissive grant that is suitable only for testing purposes:
90+
This is a permissive grant that is suitable for testing purposes:
8391

8492
```json
8593
"grants": [
@@ -89,23 +97,75 @@ This is a permissive grant that is suitable only for testing purposes:
8997
"app": {
9098
"tailscale.com/cap/tsidp": [
9199
{
92-
// STS controls
93-
"users": ["*"],
94-
"resources": ["*"],
95-
96100
// allow access to UI
97101
"allow_admin_ui": true,
98102

99103
// allow dynamic client registration
100104
"allow_dcr": true,
105+
106+
// Secure Token Service (STS) controls
107+
"users": ["*"],
108+
"resources": ["*"],
101109
},
102110
],
103111
},
104112
},
105113
],
106114
```
107115

108-
## Application Configuration Guides
116+
## tsidp Configuration Options
117+
118+
The `tsidp-server` is configured by several command-line flags:
119+
120+
| Flag | Description | Default |
121+
| ----------------------- | -------------------------------------------------------------------------------------------------- | -------- |
122+
| `-dir <path>` | Directory path to save tsnet and tsidp state. Recommend to be set. | `""` |
123+
| `-hostname <hostname>` | hostname on tailnet. Will become `<hostname>.your-tailnet.ts.net` | `idp` |
124+
| `-port <port>` | Port to listen on | `443` |
125+
| `-local-port <port>` | Listen on `localhost:<port>`. Useful for testing | disabled |
126+
| `-use-local-tailscaled` | Use local tailscaled instead of tsnet | `false` |
127+
| `-funnel` | Use Tailscale Funnel to make tsidp available on the public internet so it works with SaaS products | disabled |
128+
| `-enable-sts` | Enable OAuth token exchange using RFC 8693 | disabled |
129+
| `-log <level>` | Set logging level: `debug`, `info`, `warn`, `error` | `info` |
130+
| `-debug-all-requests` | For development. Prints all requests and responses | disabled |
131+
| `-debug-tsnet` | For development. Enables debug level logging with tsnet connection | disabled |
132+
133+
### CLI Environment Variables
134+
135+
The `tsidp-server` binary is configured through the CLI flags above. However, there are several environment variables that configure the libraries `tsidp-server` uses to connect to the Tailnet.
136+
137+
#### Required
138+
139+
- `TAILSCALE_USE_WIP_CODE=1`: required while tsidp is in development (<v1.0.0).
140+
141+
#### Optional
142+
143+
These environment variables are used when tsidp does not have any state information set in `-dir <path>`.
144+
145+
- `TS_AUTHKEY=<key>`: Key for registering a tsidp as a new node on your tailnet. If omitted a link will be printed to manually register.
146+
- `TSNET_FORCE_LOGIN=1`: Force re-login of the node. Useful during development.
147+
148+
### Docker Environment Variables
149+
150+
The Docker image exposes the CLI flags through environment variables. If omitted the default values for the CLI flags will be used.
151+
152+
> [!NOTE] > `TS_STATE_DIR` and `TS_HOSTNAME` are legacy names. These will be replaced by `TSIDP_STATE_DIR` and `TSIDP_HOSTNAME` in the future.
153+
154+
| Environment Variable | CLI flag |
155+
| ---------------------------------------- | -------------------------- |
156+
| `TS_STATE_DIR=<path>` _\*note prefix_ | `-dir <path>` |
157+
| `TS_HOSTNAME=<hostname>` _\*note prefix_ | `-hostname <hostname>` |
158+
| `TSIDP_PORT=<port>` | `-port <port>` |
159+
| `TSIDP_LOCAL_PORT=<port>` | `-local-port <port>` |
160+
| `TSIDP_PORT=<port>` | `-port <port>` |
161+
| `TSIDP_LOCAL_PORT=<local-port>` | `-local-port <local-port>` |
162+
| `TSIDP_USE_FUNNEL=1` | `-funnel` |
163+
| `TSIDP_ENABLE_STS=1` | `-enable-sts` |
164+
| `TSIDP_LOG=<level>` | `-log <level>` |
165+
| `TSIDP_DEBUG_TSNET=1` | `-debug-tsnet` |
166+
| `TSIDP_DEBUG_ALL_REQUESTS=1` | `-debug-all-requests` |
167+
168+
## Application Configuration Guides (WIP)
109169

110170
tsidp can be used as IdP server for any application that supports custom OIDC providers.
111171

@@ -126,42 +186,6 @@ tsidp supports all of the endpoints required & suggested by the [MCP Authorizati
126186
- [MCP Client / Server](./examples/mcp-server/README.md)
127187
- [MCP Client / Gateway Server](./examples/mcp-gateway/README.md)
128188

129-
## tsidp Configuration Options
130-
131-
The `tsidp` server is configured by several command-line flags:
132-
133-
- `-verbose`: Enable verbose logging
134-
- `-port`: Port to listen on (default: 443)
135-
- `-local-port`: Allow requests from localhost
136-
- `-use-local-tailscaled`: Use local tailscaled instead of tsnet
137-
- `-funnel`: Use Tailscale Funnel to make tsidp available on the public internet so it works with SaaS products
138-
- `-hostname`: tsnet hostname
139-
- `-dir`: tsnet state directory
140-
- `-enable-sts`: Enable OAuth token exchange using RFC 8693
141-
- `-enable-debug`: Enable debug printing of requests to the server
142-
143-
### Environment Variables
144-
145-
These are needed while tsidp is in development (< v1.0.0):
146-
147-
- `TAILSCALE_USE_WIP_CODE`: Enable work-in-progress code (default: "1", required)
148-
- `TS_AUTHKEY`: Your Tailscale authentication key (required)
149-
150-
The docker container accepts environment variables that are mapped to the command-line flags:
151-
152-
| Environment Variable | CLI flag |
153-
| ------------------------------- | -------------------------- |
154-
| `TS_HOSTNAME=<hostname>` | `-hostname <hostname>` |
155-
| `TS_STATE_DIR=<directory>` | `-dir <directory>` |
156-
| `TSIDP_USE_FUNNEL=1` | `-funnel` |
157-
| `TSIDP_PORT=<port>` | `-port <port>` |
158-
| `TSIDP_LOCAL_PORT=<local-port>` | `-local-port <local-port>` |
159-
| `TSIDP_ENABLE_STS=1` | `-enable-sts` |
160-
| `TSIDP_VERBOSE=1` | `-verbose` |
161-
| `TSIDP_ENABLE_DEBUG=1` | `-enable-debug` |
162-
163-
All environment variables are optional. When omitted the default value for the command-line flag will be used.
164-
165189
## Support
166190

167191
This is an experimental, work in progress, [community project](https://tailscale.com/kb/1531/community-projects). For issues or questions, file issues on the [GitHub repository](https://github.com/tailscale/tsidp).

scripts/docker/run.sh

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,26 @@ if [ -n "$TSIDP_LOCAL_PORT" ]; then
2727
ARGS="$ARGS -local-port=$TSIDP_LOCAL_PORT"
2828
fi
2929

30-
#
31-
# These flags will eventually be replaced
32-
# with more specific logging flags.
33-
#
34-
if [ -n "$TSIDP_VERBOSE" ]; then
35-
ARGS="$ARGS -verbose"
36-
fi
37-
38-
if [ -n "$TSIDP_ENABLE_DEBUG" ]; then
39-
ARGS="$ARGS -enable-debug"
30+
# logging control
31+
if [ -n "$TSIDP_LOG" ]; then
32+
case "$TSIDP_LOG" in
33+
debug|info|warn|error)
34+
ARGS="$ARGS -log=$TSIDP_LOG"
35+
;;
36+
*)
37+
echo "Error: TSIDP_LOG_LEVEL must be one of: debug, info, warn, error"
38+
echo "Current value: $TSIDP_LOG"
39+
exit 1
40+
;;
41+
esac
42+
fi
43+
44+
if [ -n "$TSIDP_DEBUG_ALL_REQUESTS" ]; then
45+
ARGS="$ARGS -debug-all-requests"
46+
fi
47+
48+
if [ -n "$TSIDP_DEBUG_TSNET" ]; then
49+
ARGS="$ARGS -debug-tsnet"
4050
fi
4151

4252
# Execute tsidp-server with the built arguments

server/appcap.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package server
55

66
import (
77
"context"
8-
"fmt"
98
"net/http"
109
"net/netip"
1110

@@ -91,13 +90,13 @@ func (s *IDPServer) addGrantAccessContext(handler http.HandlerFunc) http.Handler
9190

9291
who, err = s.lc.WhoIs(r.Context(), remoteAddr)
9392
if err != nil {
94-
http.Error(w, fmt.Sprintf("Error getting WhoIs: %v", err), http.StatusInternalServerError)
93+
writeHTTPError(w, r, http.StatusInternalServerError, ecServerError, "Error getting WhoIs", err)
9594
return
9695
}
9796

9897
rules, err := tailcfg.UnmarshalCapJSON[capRule](who.CapMap, "tailscale.com/cap/tsidp")
9998
if err != nil {
100-
http.Error(w, fmt.Sprintf("failed unmarshaling app cap rule %s", err.Error()), http.StatusInternalServerError)
99+
writeHTTPError(w, r, http.StatusInternalServerError, ecServerError, "failed unmarshaling app cap rule", err)
101100
return
102101
}
103102
accessRules.rules = rules

0 commit comments

Comments
 (0)