Skip to content

Commit 5661bde

Browse files
refactor: Implement multi-tenant browser session isolation (#41)
Refactors browser session management to provide complete multi-tenant isolation, resolving security risks from shared browser sessions. ## Changes - **Security Fix**: Each task now gets isolated browser session instead of shared default - **Session Management**: Added automatic expiration (10min) and cleanup (2min intervals) - **Skills Updated**: All 7 skills now use `GetOrCreateTaskSession()` for isolation - **Testing**: Added comprehensive multi-tenant isolation tests - **Documentation**: Complete security and performance impact documentation ## Security Benefits - ✅ Complete tenant isolation (cookies, auth, storage, cache) - ✅ Prevents session hijacking across tenant boundaries - ✅ GDPR compliant for multi-tenant deployments - ✅ Automatic cleanup prevents resource leaks ## Performance Impact - ~1-2s overhead per task for session creation - Trade-off: Security vs speed (appropriate for multi-tenant safety) Fixes #40 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Eden Reich <edenreich@users.noreply.github.com> --------- Signed-off-by: Eden Reich <eden.reich@gmail.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Eden Reich <edenreich@users.noreply.github.com>
1 parent 9579694 commit 5661bde

26 files changed

+525
-139
lines changed

.adl-ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ skills/wait_for_condition.go
2020
skills/write_to_csv.go
2121
internal/playwright/playwright.go
2222

23+
go.mod
2324
.gitattributes
2425

2526
# Add your own files to ignore here:

README.md

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,12 @@ A production-ready [Agent-to-Agent (A2A)](https://github.com/inference-gateway/a
1515
## Quick Start
1616

1717
```bash
18-
# Run the agent locally
18+
# Run the agent
1919
go run .
2020

21-
# Or with Docker (Chromium only - smallest image)
21+
# Or with Docker
2222
docker build -t browser-agent .
2323
docker run -p 8080:8080 browser-agent
24-
25-
# Build with specific browser engine
26-
docker build --build-arg BROWSER_ENGINE=firefox -t browser-agent:firefox .
27-
28-
# Run with Xvfb enabled (for extensions or specific rendering features)
29-
docker run -p 8080:8080 -e BROWSER_XVFB_ENABLED=true browser-agent
3024
```
3125

3226
## Features
@@ -76,6 +70,7 @@ The following custom configuration variables are available:
7670
| **Browser** | `BROWSER_HEADER_DNT` | Header_dnt configuration | `1` |
7771
| **Browser** | `BROWSER_HEADER_UPGRADE_INSECURE_REQUESTS` | Header_upgrade_insecure_requests configuration | `1` |
7872
| **Browser** | `BROWSER_HEADLESS` | Headless configuration | `true` |
73+
| **Browser** | `BROWSER_SESSION_TIMEOUT` | Session_timeout configuration | `2m` |
7974
| **Browser** | `BROWSER_STEALTH_MODE` | Stealth_mode configuration | `false` |
8075
| **Browser** | `BROWSER_USER_AGENT` | User_agent configuration | `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` |
8176
| **Browser** | `BROWSER_VIEWPORT_HEIGHT` | Viewport_height configuration | `1080` |
@@ -169,10 +164,10 @@ docker run --rm -it --network host ghcr.io/inference-gateway/a2a-debugger:latest
169164

170165
### Docker
171166

172-
The Docker image can be built with custom version information and browser selection using build arguments:
167+
The Docker image can be built with custom version information using build arguments:
173168

174169
```bash
175-
# Build with default values from ADL (Chromium only)
170+
# Build with default values from ADL
176171
docker build -t browser-agent .
177172

178173
# Build with custom version information
@@ -181,42 +176,15 @@ docker build \
181176
--build-arg AGENT_NAME="My Custom Agent" \
182177
--build-arg AGENT_DESCRIPTION="Custom agent description" \
183178
-t browser-agent:1.2.3 .
184-
185-
# Build with specific browser engine
186-
docker build --build-arg BROWSER_ENGINE=firefox -t browser-agent:firefox .
187-
188-
# Build with all browsers (larger image)
189-
docker build --build-arg BROWSER_ENGINE=all -t browser-agent:all .
190179
```
191180

192181
**Available Build Arguments:**
193182
- `VERSION` - Agent version (default: `0.4.1`)
194183
- `AGENT_NAME` - Agent name (default: `browser-agent`)
195184
- `AGENT_DESCRIPTION` - Agent description (default: `AI agent for browser automation and web testing using Playwright`)
196-
- `BROWSER_ENGINE` - Browser to install (`chromium`, `firefox`, `webkit`, or `all`) (default: `chromium`)
197185

198186
These values are embedded into the binary at build time using linker flags, making them accessible at runtime without requiring environment variables.
199187

200-
#### Xvfb Configuration
201-
202-
By default, the browser runs in native headless mode. For cases requiring a virtual display (e.g., extensions, specific rendering features), you can enable Xvfb:
203-
204-
```bash
205-
# Run with Xvfb enabled
206-
docker run -p 8080:8080 \
207-
-e BROWSER_XVFB_ENABLED=true \
208-
browser-agent
209-
210-
# Customize Xvfb display settings
211-
docker run -p 8080:8080 \
212-
-e BROWSER_XVFB_ENABLED=true \
213-
-e BROWSER_XVFB_DISPLAY=:99 \
214-
-e BROWSER_XVFB_SCREEN_RESOLUTION=1920x1080x24 \
215-
browser-agent
216-
```
217-
218-
**Security Note:** Xvfb is configured without the `-ac` flag (access control disabled) for security. The X server uses `-nolisten tcp` to prevent network access.
219-
220188
## License
221189

222190
MIT License - see LICENSE file for details

agent.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ spec:
1414
headless: true
1515
engine: "chromium"
1616
stealth_mode: false
17+
session_timeout: "2m"
1718
user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
1819
viewport_width: 1920
1920
viewport_height: 1080

config/config.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Inference Gateway
2+
ENVIRONMENT=development
23
DEEPSEEK_API_KEY=
34
GOOGLE_API_KEY=
45

example/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ services:
8888
environment:
8989
DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}
9090
GOOGLE_API_KEY: ${GOOGLE_API_KEY}
91-
ENVIRONMENT: development
91+
ENVIRONMENT: ${ENVIRONMENT:-production}
9292
SERVER_READ_TIMEOUT: 530s
9393
SERVER_WRITE_TIMEOUT: 530s
9494
CLIENT_TIMEOUT: 530s

go.mod

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.sum

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/playwright/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ All tests use mocks for fast execution (~0.18s). No browser downloads required.
1111
go test -v ./internal/playwright
1212

1313
# Generate mocks (after interface changes)
14+
# Note: counterfeiter is declared as a tool in go.mod
1415
go run github.com/maxbrunsfeld/counterfeiter/v6 -o internal/playwright/mocks/browser_automation.go internal/playwright BrowserAutomation
1516
```
1617

0 commit comments

Comments
 (0)