Skip to content

dglazer/cs4vwb

Repository files navigation

Claude Science for Verily Workbench

A production-ready custom app package that enables Claude Science to run within Verily Workbench environments, with automatic authentication handling and session management.

Overview

This repository contains a complete integration solution for running Claude Science as a Verily Workbench custom app. It includes:

  • Automatic binary download from official sources during build
  • Intelligent authentication proxy that handles nonce-based auth transparently
  • Header rewriting to satisfy Claude Science's origin/host validation
  • Auto-restart mechanism to maintain service availability
  • Iframe embedding support via security header stripping

Architecture

The integration uses a three-layer proxy architecture to work around Claude Science's authentication and validation requirements:

Workbench (iframe)
    ↓ (HTTPS)
nginx:8000 (reverse proxy)
    ↓ (HTTP, strips X-Frame-Options/CSP headers)
nonce-redirect:8002 (authentication proxy)
    ↓ (HTTP, rewrites Host/Origin/Referer, manages nonces)
Claude Science:8001 (actual service)
    ↓
Data Volume: /home/claude-user/.claude-science

Components

  1. nginx (port 8000) - Entry point for Workbench traffic

    • Strips X-Frame-Options and Content-Security-Policy headers to allow iframe embedding
    • Proxies all traffic to nonce-redirect service
  2. nonce-redirect.py (port 8002) - Python authentication proxy

    • Detects unauthenticated requests and redirects with fresh nonce
    • Rewrites Host, Origin, and Referer headers to localhost:8001
    • Filters cookies to distinguish Workbench cookies from Claude Science session cookies
    • Forwards all headers (including CSRF tokens) to Claude Science
  3. Claude Science (port 8001) - The actual Claude Science service

    • Runs as claude-user (non-root)
    • Binds to 127.0.0.1:8001 (internal only)
    • Auto-restarts on clean exit to maintain availability

Prerequisites

  • Access to a Verily Workbench workspace
  • Internet access for downloading Claude Science binary (during build)
  • Minimum 4 CPUs, 8GB RAM recommended

Quick Start

Deploy to Verily Workbench

  1. Navigate to your Verily Workbench workspace
  2. Click "Create App" → "Custom"
  3. Provide Git repository URL: https://github.com/dglazer/cs4vwb
  4. Configure compute resources (4+ CPUs, 8GB+ RAM)
  5. Click "Launch"

The Docker build will automatically:

  • Download the latest stable Claude Science binary from Google Cloud Storage
  • Install all required dependencies (bubblewrap, socat, nginx, python3)
  • Configure the three-layer proxy architecture
  • Set up data persistence volume

Access Claude Science

Once deployed:

  1. Click on the app URL in Workbench (format: https://<UUID>.workbench-app-prod.verily.com/)
  2. You'll be automatically redirected with a fresh authentication nonce
  3. Sign in with your Claude account when prompted
  4. Paste the authentication code when requested
  5. Start using Claude Science!

Technical Challenges Solved

This integration required working around several Claude Science behaviors that aren't designed for proxy/iframe environments:

1. Host Header Validation

Problem: Claude Science validates the Host header and rejects requests not matching its configured host.

Solution: nginx rewrites the Host header to localhost:8001 before proxying.

Location: nginx.conf:18

2. Nonce-Based Authentication

Problem: Claude Science uses single-use nonce URLs (?nonce=xxx) for authentication. Workbench loads the app without a nonce, causing immediate "session expired" errors.

Solution: Created nonce-redirect.py that:

  • Detects unauthenticated requests (no nonce, no valid session cookie)
  • Executes claude-science url to generate a fresh nonce
  • Redirects the user to the same URL with ?nonce=xxx appended

Location: nonce-redirect.py:101-155

3. Iframe Embedding Blocked

Problem: Claude Science returns X-Frame-Options: DENY and Content-Security-Policy headers that prevent iframe embedding (required by Workbench).

Solution: nginx strips these headers before returning responses to Workbench.

Location: nginx.conf:11-12

4. Origin Validation

Problem: Claude Science validates the Origin and Referer headers, rejecting requests from Workbench's domain.

Solution: nonce-redirect proxy rewrites Origin to http://localhost:8001 and Referer to http://localhost:8001/.

Location: nonce-redirect.py:26-28

5. Cookie Filtering

Problem: Workbench sends many cookies (IAP, analytics, etc.) alongside Claude Science session cookies. Need to distinguish between them to detect authenticated sessions.

Solution: Implemented cookie filtering that recognizes known Workbench cookie prefixes (GCP_IAP_UID, AMCVS_, _ga, etc.) and treats any other cookie as a potential Claude Science session.

Location: nonce-redirect.py:71-99

6. CSRF Token Forwarding

Problem: Claude Science uses CSRF tokens in cookies and request headers. Initial implementation only whitelisted specific headers, dropping CSRF tokens and causing 403 errors.

Solution: Changed to forward ALL headers from original request, then override only the specific ones that need rewriting (Host, Origin, Referer).

Location: nonce-redirect.py:20-28

7. Clean Exit Behavior

Problem: Claude Science exits cleanly (exit code 0) after ~3 minutes, possibly due to:

  • Detecting no direct connections (all traffic comes through proxies)
  • --allow-ephemeral-data-dir triggering auto-shutdown
  • Internal timeout or health check

Solution: Implemented auto-restart loop in entrypoint.sh that:

  • Monitors Claude Science process
  • If exit code is 0: automatically restart after 2 seconds
  • If exit code is non-zero: log error, sleep 5 minutes (for debugging), then exit

Location: entrypoint.sh:113-142

Impact: User sessions may be interrupted during restart, but authentication should persist via the data volume and nonce-redirect will handle re-authentication if needed.

File Structure

.
├── .devcontainer.json       # Workbench devcontainer config
├── docker-compose.yaml      # Service definition (container must be named "application-server")
├── Dockerfile               # Downloads Claude Science, installs dependencies
├── entrypoint.sh           # Startup script with auto-restart loop
├── nginx.conf              # Reverse proxy config (strips security headers)
├── nonce-redirect.py       # Authentication proxy (handles nonces, header rewriting)
├── .gitignore              # Excludes binary, data directory, logs
└── README.md               # This file

Configuration Details

Environment Variables

  • CLAUDE_SCIENCE_DATA_DIR=/home/claude-user/.claude-science - Data persistence location (mounted as Docker volume)

Ports

  • 8000: External port exposed to Workbench (nginx)
  • 8001: Internal port for Claude Science (not exposed)
  • 8002: Internal port for nonce-redirect service (not exposed)

User Permissions

  • Entrypoint runs as root to start nginx and nonce-redirect
  • Claude Science runs as claude-user (non-root) via su - claude-user
  • Data directory owned by claude-user:claude-user

Command-Line Arguments

Claude Science is started with:

serve --host 127.0.0.1 --port 8001 --no-browser --allow-ephemeral-data-dir --dangerously-no-sandbox
  • --host 127.0.0.1: Bind to localhost only (nginx proxies from external port)
  • --port 8001: Internal port
  • --no-browser: Don't attempt to open browser (no display in container)
  • --allow-ephemeral-data-dir: Allow running in container environments
  • --dangerously-no-sandbox: Disable sandbox (already in container, may lack CAP_SYS_ADMIN)

Note: These arguments are modified by entrypoint.sh from the original --host 0.0.0.0 in docker-compose.yaml.

Troubleshooting

Container fails to start

Check logs in Workbench for specific errors. Common issues:

  1. Binary download failed: Verify internet access during build
  2. Permission errors: Data directory should be owned by claude-user
  3. Port conflicts: Ensure ports 8000, 8001, 8002 are available

Authentication loops or "session expired" errors

Symptoms: Continuously redirected or asked to authenticate

Checks:

  1. Verify nonce-redirect service is running: grep "nonce-redirect" /tmp/entrypoint.log
  2. Check if claude-science url command works: su - claude-user -c "CLAUDE_SCIENCE_DATA_DIR=/home/claude-user/.claude-science /home/claude-user/claude-science url"
  3. Examine cookie filtering logic in logs

"Forbidden origin" or "Forbidden host" errors

Symptoms: {"detail":"forbidden origin"} or {"detail":"forbidden host"}

Solution: Verify header rewriting is working:

  1. Check nginx config has proxy_set_header Host localhost:8001
  2. Check nonce-redirect is rewriting Origin/Referer headers
  3. Look for header logs in [nonce-redirect] output

App becomes unresponsive after a few minutes

Symptoms: Page shows "reloading" or hangs

Likely cause: Claude Science exited and hasn't restarted yet

Check:

  1. Look for "Claude Science exited with code" messages in logs
  2. Verify auto-restart loop is working (should see "Starting Claude Science..." repeatedly)
  3. If restart loop isn't working, check entrypoint.sh syntax

403 errors on POST requests

Symptoms: Authentication works but actions fail with HTTP 403

Cause: CSRF tokens not being forwarded

Solution: Verify nonce-redirect.py copies ALL headers (line 20-23), not just whitelisted ones

Future Enhancements

Short-term Improvements

  1. Health checks: Add proper health endpoints to monitor service status
  2. Graceful restarts: Attempt to preserve sessions during Claude Science restarts
  3. Configurable restart delay: Make the 2-second restart delay configurable
  4. Better logging: Add structured logging with timestamps and severity levels
  5. Metrics: Expose Prometheus metrics for restart frequency, authentication failures, etc.

Medium-term Improvements

  1. Session persistence: Investigate if sessions can be preserved across restarts
  2. Connection pooling: Optimize proxy connections for better performance
  3. Custom error pages: Provide helpful error pages instead of generic 500/502 errors
  4. Automatic version updates: Script to check for and download new Claude Science versions
  5. Multi-user support: Handle multiple concurrent users more robustly

Long-term Improvements

  1. Horizontal scaling: Support multiple Claude Science instances behind a load balancer
  2. WebSocket optimization: Improve WebSocket handling for real-time features
  3. SSO integration: Integrate with Workbench's authentication instead of separate Claude login
  4. Resource management: Automatic CPU/memory allocation based on usage

Claude Science Enhancement Requests

These are suggested changes to Claude Science that would make integrations like this much cleaner and more robust:

Critical Priority

  1. Configuration-based host/origin validation

    • Current behavior: Hard-coded validation against expected host/origin
    • Desired: Environment variables or config file to specify allowed hosts/origins
    • Example: ALLOWED_ORIGINS=https://example.com,https://*.workbench-app-prod.verily.com
    • Impact: Would eliminate need for header rewriting proxies
  2. Optional iframe embedding support

    • Current behavior: Always sends X-Frame-Options: DENY and restrictive CSP
    • Desired: Flag like --allow-iframe-embedding to omit these headers
    • Impact: Would eliminate need for nginx header stripping
  3. Token-based authentication alternative

    • Current behavior: Only nonce-based auth (single-use URLs)
    • Desired: Support long-lived API tokens or OAuth flows
    • Impact: Would eliminate need for nonce-redirect proxy entirely

High Priority

  1. Long-running service mode

    • Current behavior: Appears to exit after inactivity or due to ephemeral data dir
    • Desired: Explicit --daemon mode that runs indefinitely
    • Impact: Would eliminate need for auto-restart loop
  2. Session persistence documentation

    • Current behavior: Unclear what state persists across restarts
    • Desired: Document what's stored in data directory vs. memory
    • Impact: Would help understand restart behavior and session continuity
  3. Proxy-friendly networking

    • Current behavior: Unclear how it detects connections (may see no clients when behind proxies)
    • Desired: Option to trust X-Forwarded-For headers and consider proxied connections as active
    • Impact: May prevent premature exits when behind proxies

Medium Priority

  1. Structured logging

    • Current behavior: Human-readable text logs
    • Desired: Option for JSON-structured logs with severity levels
    • Impact: Easier to parse and monitor in container environments
  2. Health check endpoint

    • Current behavior: No dedicated health endpoint
    • Desired: /health or /ready endpoint that returns service status
    • Impact: Better integration with orchestrators (Docker, Kubernetes, Workbench)
  3. Graceful shutdown

    • Current behavior: Unknown shutdown behavior
    • Desired: Handle SIGTERM/SIGINT gracefully, finish in-flight requests
    • Impact: Better session continuity during restarts
  4. Configuration file support

    • Current behavior: All configuration via CLI flags
    • Desired: Support for config file (YAML/TOML) for complex setups
    • Impact: Easier to manage in container environments

Nice to Have

  1. Multi-user mode

    • Current behavior: Designed for single local user
    • Desired: Built-in support for multiple concurrent authenticated users
    • Impact: Better fit for shared/enterprise environments like Workbench
  2. Metrics endpoint

    • Current behavior: No metrics exposure
    • Desired: Prometheus-compatible /metrics endpoint
    • Impact: Better observability in production deployments
  3. Configurable authentication timeout

    • Current behavior: Fixed session timeout (unknown duration)
    • Desired: --session-timeout=24h flag
    • Impact: Reduce re-authentication frequency in trusted environments

Known Limitations

  1. Session interruption on restart: When Claude Science restarts (every ~3 minutes), active sessions may be interrupted
  2. Single instance only: Currently supports only one Claude Science instance per container
  3. No offline mode: Requires internet access for authentication
  4. Limited error handling: Some proxy errors may not have helpful error messages

Contributing

Improvements welcome! Areas where contributions would be particularly valuable:

  • Testing session persistence across restarts
  • Improving auto-restart logic to minimize disruption
  • Adding health checks and metrics
  • Testing with multiple concurrent users
  • Documenting Claude Science's actual exit behavior

Support

For issues with:

License

This integration configuration is provided as-is under MIT License. Claude Science is subject to Anthropic's license terms.

Acknowledgments

Built through iterative debugging across 31 deployment attempts, solving challenges with:

  • Host/origin validation
  • Nonce-based authentication in iframe contexts
  • Cookie filtering across proxy boundaries
  • CSRF token preservation
  • Service availability and auto-restart

Special thanks to the Verily Workbench team for the custom app platform and documentation.

About

Claude Science custom app for Verily Workbench

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors