Capture e2e and regression test traffic as a TLS-decryptable capture bundle and upload it to S3.
-
start/— Installs either Fluxzy or mitmproxy as a forward proxy, trusts its root CA on the OS, and exportsHTTP_PROXY/HTTPS_PROXYso downstream tests route through the proxy automatically. Fluxzy is the default. Optionally startstcpdump(Linux) ornetsh trace(Windows) for raw packet capture whenraw-capture: true. -
stop/— Stops the proxy and packet capture, bundles the PCAP + TLS session keys (SSLKEYLOGFILE) + CA cert into a.tar.gz. The S3 upload runs as a post step so it executes even if subsequent steps fail.
When proxy-tool: mitmproxy, filtering happens inline in the mitmproxy addon.
The resulting bundle can be opened in Wireshark with full TLS decryption using the included sslkeys.log file.
This action currently supports two proxy engines:
- Fluxzy (Default): High-performance .NET-based proxy. Best for x86_64 runners.
- mitmproxy: Python-based proxy with excellent ARM64 support. Automatically selected if running on an ARM64 node, or can be forced via
proxy-type.
You can filter captured traffic using the filter-rules input.
- Fluxzy: Uses a comma-separated list of host filters (e.g.,
example.com,test.org). - mitmproxy: Uses standard mitmproxy filter expressions (e.g.,
~u example.com & ~m POST).
Use custom-rules-file to provide tool-native custom behavior in addition to existing inputs (filter-*, strip-*, ignore-hosts).
- Fluxzy: Interpreted as a Fluxzy rules YAML file and loaded with
-r. If generated rules from this action also exist, both rule sets are combined and applied. Docs: Fluxzy repository/documentation - mitmproxy: Interpreted as a mitmproxy Python addon script and loaded with
--scripts. It runs in addition to the action's built-in addon. Docs: mitmproxy addons overview
Path resolution supports both absolute paths and workspace-relative paths.
jobs:
e2e:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/my-role
aws-region: us-east-1
# Start capturing BEFORE e2e tests
- uses: caseware/capture-pcap-action/start@v1
id: pcap
with:
proxy-tool: fluxzy
# Your e2e tests run here — HTTP_PROXY/HTTPS_PROXY are set automatically
- name: Run e2e tests
run: npx playwright test
# Stop capturing AFTER e2e tests — S3 upload runs as a post step
- uses: caseware/capture-pcap-action/stop@v1
with:
s3-bucket: my-pcap-bucket
s3-prefix: e2e/${{ github.run_id }}Only capture traffic to your own services:
- uses: caseware/capture-pcap-action/start@v1
with:
filter-domains: '*.caseware.com,*.cwcloudtest.com'
filter-exclude-domains: '*.analytics.google.com'
filter-content-types: 'text/html,application/json'
filter-max-body-size: '1048576' # 1 MB - uses: caseware/capture-pcap-action/stop@v1
with:
s3-bucket: test-bucket
s3-endpoint: http://localhost:9000| Input | Default | Description |
|---|---|---|
proxy-tool |
fluxzy |
Proxy tool to run: fluxzy or mitmproxy |
proxy-port |
8080 |
Port for the mitmproxy forward proxy |
capture-dir |
$RUNNER_TEMP/pcap-capture |
Directory for capture artifacts |
process-name |
(empty) | (reserved, not yet implemented) Process name filter |
mitmproxy-version |
11.0.2 |
mitmproxy version to install |
fluxzy-version |
latest |
Fluxzy CLI version to install when proxy-tool=fluxzy |
filter-domains |
(empty) | Domain allowlist (comma-sep, globs OK, e.g. *.caseware.com) |
filter-exclude-domains |
(empty) | Domain denylist (comma-sep, globs OK) |
filter-referers |
(empty) | Referer patterns to keep (comma-sep, globs OK) |
filter-content-types |
(empty) | Content-type prefixes to keep (e.g. text/html,application/json) |
filter-max-body-size |
0 |
Max response body size in bytes (0 = no limit) |
custom-rules-file |
(empty) | Single custom rules input. Fluxzy: rules YAML (-r). mitmproxy: addon script (--scripts). |
raw-capture |
false |
Also run tcpdump/netsh for raw packet capture alongside mitmproxy |
no-proxy |
cloud.nx.app,nx.app,registry.npmjs.org,objects.githubusercontent.com,localhost,127.0.0.1,::1 |
Comma-separated hosts that bypass the proxy (NO_PROXY) |
| Input | Default | Description |
|---|---|---|
capture-dir |
(from env) | Capture directory (auto-detected from start action) |
s3-bucket |
(empty) | S3 bucket name. Leave empty to skip upload and keep bundle local only |
s3-prefix |
pcap-captures |
S3 key prefix |
s3-endpoint |
(empty) | Custom S3 endpoint URL |
artifact-name |
(timestamped) | Name for the capture bundle |
Note: The stop action's S3 upload runs as a post step when
s3-bucketis set — it will execute at job cleanup time even if later steps fail. Ifs3-bucketis empty, upload is skipped and artifacts remain local.
| Output | Description |
|---|---|
capture-dir |
Path to the capture artifacts directory |
ca-cert |
Path to the proxy root CA certificate |
proxy-url |
Proxy URL (http://127.0.0.1:<port>) |
| Output | Description |
|---|---|
pcap-file |
Path to the raw PCAP file |
sslkeylog-file |
Path to the TLS session keys file |
bundle-path |
Local path to the .tar.gz bundle |
s3-uri |
S3 URI of the uploaded bundle (set in post step) |
Filtering is applied inline when proxy-tool: mitmproxy via the addon (scripts/filter-addon.py) at request/response time.
When raw-capture: true is set, the raw PCAP (tcpdump/netsh) captures all
packets regardless of the filter. This is useful for debugging network issues
that the proxy filter might mask. Use the sslkeys.log + PCAP in Wireshark
for full visibility, and capture.har for the filtered proxy view.
By default (raw-capture: false), only the selected proxy runs — this is lighter,
faster, and avoids the sudo/admin requirements of tcpdump/netsh.
- Download and extract the bundle from S3
- Open
raw-capture.pcapin Wireshark - Go to Edit > Preferences > Protocols > TLS
- Set (Pre)-Master-Secret log filename to
sslkeys.log - All TLS traffic will be decrypted
- uses: caseware/capture-pcap-action/start@v1
with:
filter-domains: '*.caseware.com,*.cwcloudtest.com'
# ... existing e2e test steps ...
- uses: caseware/capture-pcap-action/stop@v1
with:
s3-bucket: ${{ vars.PCAP_S3_BUCKET }}
s3-prefix: pr/${{ github.event.pull_request.number }} - uses: caseware/capture-pcap-action/start@v1
# ... existing regression test steps ...
- uses: caseware/capture-pcap-action/stop@v1
with:
s3-bucket: ${{ vars.PCAP_S3_BUCKET }}
s3-prefix: nightly/${{ github.run_id }}