You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Initial plan
* feat: add rust one-shot-token library implementation
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* docs: update README for rust implementation
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* feat: update Dockerfile and entrypoint for rust build
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* fix(security): use multi-stage build for rust compilation
Use official rust:1.77-slim Docker image in multi-stage build to avoid
executing unverified rustup installer script. This mitigates supply
chain attack risk during container builds.
Changes:
- Add rust-builder stage using rust:1.77-slim official image
- Build one-shot-token library in isolated builder stage
- Copy pre-built library to main stage via COPY --from=rust-builder
- Remove curl/build-essential from main stage (no longer needed)
- Add security comments documenting supply chain attack mitigation
Addresses security review recommendation from @lpcox.
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* feat(ci): add crates.io to build-test-rust network allowlist
* chore(ci): regenerate build-test-rust lock file with crates.io
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* fix: correct exit code success detection in test runner (#793)
* Initial plan
* fix: correct exit code success detection in test runner
The awf-runner was incorrectly handling undefined exit codes from execa.
When exitCode was undefined, it would set exitCode field to 0 (via || operator)
but success field would evaluate undefined === 0 which is false.
This caused tests to fail with the confusing message:
"Expected awf to succeed, but it failed with exit code 0"
Fixed by normalizing exitCode to a variable first using ?? operator,
then using that normalized value for both fields.
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
---------
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* Initial plan (#794)
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
* fix: add Rust toolchain setup and RUSTUP_HOME support for chroot package manager tests (#797)
* Initial plan
* fix: add explicit toolchain to rust setup in test workflow
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
* feat: add RUSTUP_HOME environment variable support for Rust toolchain
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
---------
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
---------
Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Requires Rust toolchain (install via [rustup](https://rustup.rs/)):
171
+
172
172
```bash
173
173
./build.sh
174
174
```
175
175
176
-
This produces `one-shot-token.so`in the current directory.
176
+
This builds `target/release/libone_shot_token.so` and creates a symlink `one-shot-token.so`for backwards compatibility.
177
177
178
178
## Testing
179
179
@@ -274,6 +274,20 @@ Note: The `AWF_ONE_SHOT_TOKENS` variable must be exported before running `awf` s
274
274
-**In-process getenv() calls**: Since values are cached, any code in the same process can still call `getenv()` and get the cached token
275
275
-**Static linking**: Programs statically linked with libc bypass LD_PRELOAD
276
276
-**Direct syscalls**: Code that reads `/proc/self/environ` directly (without getenv) bypasses this protection
277
+
-**Task-level /proc exposure**: `/proc/PID/task/TID/environ` may still expose tokens even after `unsetenv()`. The library checks and logs warnings about this exposure.
278
+
279
+
### Environment Verification
280
+
281
+
After calling `unsetenv()` to clear tokens, the library automatically verifies whether the token was successfully removed by directly checking the process's environment pointer. This works correctly in both regular and chroot modes.
282
+
283
+
**Log messages:**
284
+
-`INFO: Token <name> cleared from process environment` - Token successfully cleared (✓ secure)
285
+
-`WARNING: Token <name> still exposed in process environment` - Token still visible (⚠ security concern)
286
+
-`INFO: Token <name> cleared (environ is null)` - Environment pointer is null
287
+
288
+
This verification runs automatically after `unsetenv()` on first access to each sensitive token and helps identify potential security issues with environment exposure.
289
+
290
+
**Note on chroot mode:** The verification uses the process's `environ` pointer directly rather than reading from `/proc/self/environ`. This is necessary because in chroot mode, `/proc` may be bind-mounted from the host and show stale environment data.
277
291
278
292
### Defense in Depth
279
293
@@ -285,12 +299,13 @@ This library is one layer in AWF's security model:
285
299
286
300
## Limitations
287
301
288
-
-**x86_64 Linux only**: The library is compiled for x86_64 Ubuntu
302
+
-**Linux only**: The library is compiled for Linux (x86_64 and potentially other architectures via Rust cross-compilation)
289
303
-**glibc programs only**: Programs using musl libc or statically linked programs are not affected
290
304
-**Single process**: Child processes inherit the LD_PRELOAD but have their own token state and cache (each starts fresh)
0 commit comments