ask-sandbox-providers 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +21 -92
- data/lib/ask/sandbox/local.rb +5 -1
- data/lib/ask/sandbox/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bb95b1b00d2c4ed3bb7e3e9a98f77d9035b8c3cc5e990b47870e3edec87f4ea8
|
|
4
|
+
data.tar.gz: 64781ff4c3f4e8020d759cdef227a05b9f4a21f0b36a6bbb6776aca8849310f5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a14deb3e21c8ae4f73b65fd20d5f5eb6176ea871f6184fc18ecf826285ea1c150fa2f22fdf3a03d33e4602f817c7401f1e2da976a1b0fee6e451d880a39e5278
|
|
7
|
+
data.tar.gz: 3a1480416aa824fc853bdb6da60d278cad5699c6e8571d3d0bcd2bd5626f07a24b3664f884f7c7ac9166eaede264bfb954b2a8e1839a93bd9a566d819e9de9aa
|
data/README.md
CHANGED
|
@@ -2,14 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/ask-sandbox-providers)
|
|
4
4
|
|
|
5
|
-
Sandbox providers for the ask-rb ecosystem
|
|
6
|
-
|
|
7
|
-
| Provider | Isolation | Speed | Requirement |
|
|
8
|
-
|---|---|---|---|
|
|
9
|
-
| `Local` | Process + rlimits (CPU, memory, processes, file size) | Instant | None (stdlib) |
|
|
10
|
-
| `Docker` | Full container (read-only rootfs, no network, no capabilities) | ~1s | Docker daemon |
|
|
11
|
-
| `Daytona` | Remote container via Daytona API | ~2-5s | `daytona` gem, API key |
|
|
12
|
-
| `Cloudflare` | Cloudflare Workers sandbox via proxy Worker | ~1-3s | Proxy Worker URL |
|
|
5
|
+
Sandbox providers for the ask-rb ecosystem: isolated code execution with a single interface and four backends. The default Local provider needs nothing; Docker, Daytona, and Cloudflare add stronger or remote isolation.
|
|
13
6
|
|
|
14
7
|
## Installation
|
|
15
8
|
|
|
@@ -22,106 +15,42 @@ gem "ask-sandbox-providers"
|
|
|
22
15
|
```ruby
|
|
23
16
|
require "ask-sandbox-providers"
|
|
24
17
|
|
|
25
|
-
|
|
26
|
-
result
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
puts result.timed_out # => false
|
|
18
|
+
result = Ask::Sandbox.provider.call(["ruby", "-e", "puts 1 + 1"])
|
|
19
|
+
result.stdout # => "1\n"
|
|
20
|
+
result.exit_code # => 0
|
|
21
|
+
result.success? # => true
|
|
30
22
|
```
|
|
31
23
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```ruby
|
|
35
|
-
# Docker (requires Docker daemon)
|
|
36
|
-
Ask::Sandbox.provider = Ask::Sandbox::Docker.new(
|
|
37
|
-
image: "ruby:3.4-alpine",
|
|
38
|
-
memory: "256m",
|
|
39
|
-
network: false
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
# Daytona (requires `daytona` gem + API key)
|
|
43
|
-
Ask::Sandbox.provider = Ask::Sandbox::Daytona.new(
|
|
44
|
-
api_key: Ask::Auth.lookup("DAYTONA_API_KEY"),
|
|
45
|
-
server_url: "https://api.daytona.io"
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
# Cloudflare (requires a deployed proxy Worker)
|
|
49
|
-
Ask::Sandbox.provider = Ask::Sandbox::Cloudflare.new(
|
|
50
|
-
worker_url: "https://sandbox-proxy.my-worker.workers.dev",
|
|
51
|
-
auth_token: ENV["CLOUDFLARE_SANDBOX_TOKEN"]
|
|
52
|
-
)
|
|
53
|
-
```
|
|
24
|
+
Commands can be an Array (executed directly, no shell) or a String (executed via `bash -c`). All providers accept `call(command, timeout: 30, workdir: nil, env: {}, stdin: nil)`.
|
|
54
25
|
|
|
55
|
-
|
|
26
|
+
## Choosing a provider
|
|
56
27
|
|
|
57
28
|
```ruby
|
|
58
|
-
#
|
|
59
|
-
Ask::Sandbox.provider.call("ls -la | head -5")
|
|
29
|
+
Ask::Sandbox.provider = :docker # symbol shortcuts: :local, :docker, :daytona, :cloudflare
|
|
60
30
|
|
|
61
|
-
|
|
62
|
-
Ask::Sandbox.provider.call(["ruby", "-e", "puts ENV['HOME']"])
|
|
31
|
+
Ask::Sandbox.provider = Ask::Sandbox::Docker.new(image: "ruby:3.4-alpine", memory: "256m", network: false)
|
|
63
32
|
```
|
|
64
33
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Provider Details
|
|
74
|
-
|
|
75
|
-
### Local
|
|
76
|
-
|
|
77
|
-
The default provider. Runs commands in a temp directory with:
|
|
34
|
+
| Provider | Isolation | Requirement |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `Ask::Sandbox::Local` (default) | Subprocess with rlimits (CPU, memory, processes, file size), temp directory, sanitized environment | None, stdlib only |
|
|
37
|
+
| `Ask::Sandbox::Docker` | Container with read-only rootfs, no capabilities, no network | Docker daemon |
|
|
38
|
+
| `Ask::Sandbox::Daytona` | Remote sandbox via the Daytona API | `daytona` gem, API key |
|
|
39
|
+
| `Ask::Sandbox::Cloudflare` | Cloudflare Workers sandbox via a proxy Worker | Deployed proxy Worker URL |
|
|
78
40
|
|
|
79
|
-
|
|
80
|
-
- **`Process.setrlimit`** — CPU (10s), address space (2GB), processes (50), file size (10MB), FDs (200)
|
|
81
|
-
- **Temp directory** — execution sandbox is auto-cleaned
|
|
82
|
-
- **Environment sanitization** — Bundler/Ruby env vars stripped
|
|
41
|
+
Daytona resolves its API key from `Ask::Auth.lookup("DAYTONA_API_KEY")` or `ENV["DAYTONA_API_KEY"]` when `api_key:` is not given. Cloudflare falls back to the `CLOUDFLARE_SANDBOX_WORKER_URL` and `CLOUDFLARE_SANDBOX_AUTH_TOKEN` env vars.
|
|
83
42
|
|
|
84
|
-
|
|
43
|
+
## Result
|
|
85
44
|
|
|
86
|
-
|
|
45
|
+
Every provider returns `Ask::Sandbox::Result`, a `Data` object with `stdout`, `stderr`, `exit_code`, and `timed_out` fields, plus `#success?` (true when `exit_code == 0`).
|
|
87
46
|
|
|
88
|
-
|
|
47
|
+
## Full documentation
|
|
89
48
|
|
|
90
|
-
-
|
|
91
|
-
- `--cap-drop ALL` — no Linux capabilities
|
|
92
|
-
- `--security-opt no-new-privileges` — no privilege escalation
|
|
93
|
-
- `--network none` — no network egress (configurable)
|
|
94
|
-
- `--memory`, `--cpus`, `--pids-limit` — resource limits
|
|
95
|
-
- `--rm` — auto-cleanup on exit
|
|
96
|
-
|
|
97
|
-
### Daytona
|
|
98
|
-
|
|
99
|
-
Runs commands in a Daytona sandbox via the official `daytona` gem. Daytona provides secure, elastic sandboxes with full isolation, dedicated kernel, filesystem, and network stack. See [daytona.io/docs](https://www.daytona.io/docs).
|
|
100
|
-
|
|
101
|
-
### Cloudflare
|
|
102
|
-
|
|
103
|
-
Runs commands in a Cloudflare Workers sandbox. Requires deploying a proxy Worker that wraps `@cloudflare/sandbox`. See the [Cloudflare Sandbox SDK docs](https://developers.cloudflare.com/sandbox/) for setup.
|
|
104
|
-
|
|
105
|
-
## Migration from Direct Open3 Usage
|
|
106
|
-
|
|
107
|
-
If you're upgrading from `ask-tools-shell` v0.1.0 where `Code` and `Bash` tools called
|
|
108
|
-
`Open3.popen3` directly — no action needed. The default `Ask::Sandbox::Local` provider
|
|
109
|
-
behaves identically. To enable stronger isolation, switch the provider:
|
|
110
|
-
|
|
111
|
-
```ruby
|
|
112
|
-
# Before: direct Open3 (implicit Local)
|
|
113
|
-
Ask::Tools::Code.new.call(code: "puts 1")
|
|
114
|
-
|
|
115
|
-
# After: configure Docker for stronger isolation
|
|
116
|
-
Ask::Sandbox.provider = Ask::Sandbox::Docker.new
|
|
117
|
-
# The Code tool now runs code inside a Docker container automatically
|
|
118
|
-
```
|
|
49
|
+
The full ask-rb documentation lives at https://ask-rb.github.io/ask-docs. [ask-sandbox-providers in depth](https://ask-rb.github.io/ask-docs/core/sandbox) covers each provider and the hardening details. API reference: https://ask-rb.github.io/ask-docs/reference/api.
|
|
119
50
|
|
|
120
51
|
## Development
|
|
121
52
|
|
|
122
|
-
```
|
|
123
|
-
git clone https://github.com/ask-rb/ask-sandbox-providers.git
|
|
124
|
-
cd ask-sandbox-providers
|
|
53
|
+
```
|
|
125
54
|
bundle install
|
|
126
55
|
bundle exec rake test
|
|
127
56
|
```
|
data/lib/ask/sandbox/local.rb
CHANGED
|
@@ -17,7 +17,11 @@ module Ask
|
|
|
17
17
|
|
|
18
18
|
RLIMITS = {
|
|
19
19
|
rlimit_cpu: [10, 30],
|
|
20
|
-
|
|
20
|
+
# nproc limits the *user's* total process count, not the sandbox's.
|
|
21
|
+
# 200 is easily exceeded on a busy dev machine, which makes every
|
|
22
|
+
# fork in the sandboxed command fail with EAGAIN. 1024 still guards
|
|
23
|
+
# against fork bombs without breaking normal use.
|
|
24
|
+
rlimit_nproc: [1024, 1024],
|
|
21
25
|
rlimit_fsize: [10_485_760, 10_485_760],
|
|
22
26
|
rlimit_nofile: [200, 200],
|
|
23
27
|
rlimit_as: [2_147_483_648, 2_147_483_648]
|
data/lib/ask/sandbox/version.rb
CHANGED