feat(security): harden gateway request and runtime controls #1181
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Rust CI | |
| on: | |
| push: | |
| branches: | |
| - master | |
| - main | |
| paths: | |
| - "Cargo.toml" | |
| - "Cargo.lock" | |
| - "crates/**" | |
| - "apps/**" | |
| - ".github/workflows/rust-ci.yml" | |
| pull_request: | |
| paths: | |
| - "Cargo.toml" | |
| - "Cargo.lock" | |
| - "crates/**" | |
| - "apps/**" | |
| - ".github/workflows/rust-ci.yml" | |
| concurrency: | |
| group: rust-ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_PROFILE_DEV_DEBUG: 0 | |
| CARGO_PROFILE_TEST_DEBUG: 0 | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| fmt: | |
| name: Format | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.95.0 | |
| components: rustfmt | |
| - name: Format | |
| run: cargo fmt --all --check | |
| clippy_gateway: | |
| name: Clippy (Gateway) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.95.0 | |
| components: clippy | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Clippy | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: cargo clippy -p aether-gateway --lib --bins --examples -- -D warnings | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| clippy_data: | |
| name: Clippy (Data) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.95.0 | |
| components: clippy | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Clippy | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: cargo clippy -p aether-data --all-targets -- -D warnings | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| clippy_rest: | |
| name: Clippy (Workspace Rest) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.95.0 | |
| components: clippy | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Clippy | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: cargo clippy --workspace --exclude aether-gateway --exclude aether-data --all-targets -- -D warnings | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| clippy: | |
| name: Clippy | |
| runs-on: ubuntu-latest | |
| needs: | |
| - clippy_gateway | |
| - clippy_data | |
| - clippy_rest | |
| if: ${{ always() }} | |
| steps: | |
| - name: Verify clippy jobs | |
| run: | | |
| if [ "${{ needs.clippy_gateway.result }}" != "success" ] || \ | |
| [ "${{ needs.clippy_data.result }}" != "success" ] || \ | |
| [ "${{ needs.clippy_rest.result }}" != "success" ]; then | |
| echo "Clippy failed" | |
| exit 1 | |
| fi | |
| test_gateway: | |
| name: Test (Gateway) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Show Rust toolchain | |
| run: rustup show active-toolchain | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Setup mold | |
| uses: rui314/setup-mold@v1 | |
| - name: Install nextest | |
| uses: taiki-e/install-action@nextest | |
| - name: Test lib | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUST_MIN_STACK: "16777216" | |
| RUSTFLAGS: "-C link-arg=-fuse-ld=mold" | |
| run: cargo nextest run -p aether-gateway --lib | |
| - name: Test bin | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| RUST_MIN_STACK: "16777216" | |
| RUSTFLAGS: "-C link-arg=-fuse-ld=mold" | |
| run: cargo nextest run -p aether-gateway --bin aether-gateway | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| test_data: | |
| name: Test (Data) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Show Rust toolchain | |
| run: rustup show active-toolchain | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Install nextest | |
| uses: taiki-e/install-action@nextest | |
| - name: Test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: cargo nextest run -p aether-data | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| test_rest: | |
| name: Test (Workspace Rest) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Show Rust toolchain | |
| run: rustup show active-toolchain | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Install nextest | |
| uses: taiki-e/install-action@nextest | |
| - name: Test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: cargo nextest run --workspace --exclude aether-gateway --exclude aether-data | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| needs: | |
| - test_gateway | |
| - test_data | |
| - test_rest | |
| if: ${{ always() }} | |
| steps: | |
| - name: Verify test jobs | |
| run: | | |
| if [ "${{ needs.test_gateway.result }}" != "success" ] || \ | |
| [ "${{ needs.test_data.result }}" != "success" ] || \ | |
| [ "${{ needs.test_rest.result }}" != "success" ]; then | |
| echo "Tests failed" | |
| exit 1 | |
| fi | |
| data_db_smoke_sqlite: | |
| name: Data DB Smoke (SQLite) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Show Rust toolchain | |
| run: rustup show active-toolchain | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Run SQLite data smoke tests | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: cargo test -p aether-data sqlite --lib | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| data_db_smoke_postgres: | |
| name: Data DB Smoke (Postgres) | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16 | |
| env: | |
| POSTGRES_DB: aether_test | |
| POSTGRES_USER: aether | |
| POSTGRES_PASSWORD: aether | |
| ports: | |
| - 5432:5432 | |
| options: >- | |
| --health-cmd="pg_isready -h 127.0.0.1 -U aether -d aether_test" | |
| --health-interval=5s | |
| --health-timeout=5s | |
| --health-retries=20 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Show Rust toolchain | |
| run: rustup show active-toolchain | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Run Postgres migration smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_POSTGRES_URL: postgres://aether:aether@127.0.0.1:5432/aether_test | |
| run: cargo test -p aether-data postgres_migrations_create_core_config_tables_when_url_is_set --lib -- --nocapture | |
| - name: Run Postgres core export smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_POSTGRES_URL: postgres://aether:aether@127.0.0.1:5432/aether_test | |
| run: cargo test -p aether-data postgres_core_export_reads_migrated_database_rows_when_url_is_set --lib -- --nocapture | |
| - name: Run SQLite-to-Postgres import smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_POSTGRES_URL: postgres://aether:aether@127.0.0.1:5432/aether_test | |
| run: cargo test -p aether-data sqlite_core_export_reads_migrated_database_rows --lib -- --nocapture | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| data_db_smoke_mysql: | |
| name: Data DB Smoke (MySQL) | |
| runs-on: ubuntu-latest | |
| services: | |
| mysql: | |
| image: mysql:8.0 | |
| env: | |
| MYSQL_DATABASE: aether_test | |
| MYSQL_USER: aether | |
| MYSQL_PASSWORD: aether | |
| MYSQL_ROOT_PASSWORD: aether_root | |
| ports: | |
| - 3306:3306 | |
| options: >- | |
| --health-cmd="mysqladmin ping -h 127.0.0.1 -uaether -paether --silent" | |
| --health-interval=5s | |
| --health-timeout=5s | |
| --health-retries=20 | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Show Rust toolchain | |
| run: rustup show active-toolchain | |
| - name: Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: rust-ci-${{ runner.os }} | |
| workspaces: . -> target | |
| - name: Setup sccache | |
| uses: mozilla-actions/sccache-action@v0.0.9 | |
| - name: Run MySQL migration smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_migrations_create_core_config_tables_when_url_is_set --lib -- --nocapture | |
| - name: Run MySQL usage write smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_usage_write_repository_upserts_when_url_is_set --lib -- --nocapture | |
| - name: Run MySQL usage read smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_usage_read_repository_reads_usage_contract_views_when_url_is_set --lib -- --nocapture | |
| - name: Run MySQL provider catalog smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_provider_catalog_repository_round_trips_when_url_is_set --lib -- --nocapture | |
| - name: Run MySQL core export smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_core_export_reads_migrated_database_rows_when_url_is_set --lib -- --nocapture | |
| - name: Run MySQL wallet read smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_wallet_read_repository_reads_wallet_contract_views --lib -- --nocapture | |
| - name: Run MySQL wallet daily usage aggregation smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_wallet_daily_usage_aggregation_uses_settlement_wallets_when_url_is_set --lib -- --nocapture | |
| - name: Run MySQL stats aggregation smoke test | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| AETHER_TEST_MYSQL_URL: mysql://aether:aether@127.0.0.1:3306/aether_test | |
| run: cargo test -p aether-data mysql_stats_aggregation_runs_after_mysql_migrations_when_url_is_set --lib -- --nocapture | |
| - name: Show sccache stats | |
| if: always() | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_GHA_ENABLED: "true" | |
| run: sccache --show-stats | |
| data_db_smoke: | |
| name: Data DB Smoke | |
| runs-on: ubuntu-latest | |
| needs: | |
| - data_db_smoke_sqlite | |
| - data_db_smoke_postgres | |
| - data_db_smoke_mysql | |
| if: ${{ always() }} | |
| steps: | |
| - name: Verify database smoke jobs | |
| run: | | |
| if [ "${{ needs.data_db_smoke_sqlite.result }}" != "success" ] || \ | |
| [ "${{ needs.data_db_smoke_postgres.result }}" != "success" ] || \ | |
| [ "${{ needs.data_db_smoke_mysql.result }}" != "success" ]; then | |
| echo "Data DB smoke failed" | |
| exit 1 | |
| fi | |
| check: | |
| name: check | |
| runs-on: ubuntu-latest | |
| needs: | |
| - fmt | |
| - clippy | |
| - test | |
| - data_db_smoke | |
| if: ${{ always() }} | |
| steps: | |
| - name: Verify required jobs | |
| run: | | |
| if [ "${{ needs.fmt.result }}" != "success" ] || \ | |
| [ "${{ needs.clippy.result }}" != "success" ] || \ | |
| [ "${{ needs.test.result }}" != "success" ] || \ | |
| [ "${{ needs.data_db_smoke.result }}" != "success" ]; then | |
| echo "Rust CI failed" | |
| exit 1 | |
| fi |