Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .cargo/audit.toml

This file was deleted.

56 changes: 56 additions & 0 deletions .github/actions/setup-pgrx/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: setup-pgrx
description: |
Install PG dev headers, build the pgrx extension .so, copy it into the
postgres service container's pkglibdir. Caller must:
1. Define a services.postgres block on the job.
2. Pass postgres-container-id from job.services.postgres.id (the
job context is not available in job-level env, only in step inputs).
3. Have already run actions/checkout + setup-rust.
inputs:
pg-version:
description: Postgres major version (matches the postgres:N image and pg<N> feature flag).
required: false
default: "18"
extension-crate:
description: Cargo package name of the pgrx extension (e.g. beyond-auth-extension).
required: true
built-so-name:
description: Filename of the .so as cargo emits it under target/release (some pgrx crates emit lib*.so, others don't).
required: true
install-so-name:
description: Filename the postgres extension expects in pkglibdir. May differ from built-so-name when cargo emits a lib- prefix.
required: true
postgres-container-id:
description: The job's postgres service container id (from job.services.postgres.id).
required: true
runs:
using: composite
steps:
- name: install postgres ${{ inputs.pg-version }} dev headers
shell: bash
run: |
set -euo pipefail
sudo apt-get install -y gnupg2 lsb-release
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/pgdg.gpg
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
sudo apt-get install -y \
postgresql-server-dev-${{ inputs.pg-version }} libclang-dev clang
- name: build pgrx extension
shell: bash
run: |
set -euo pipefail
PGRX_PG_CONFIG_PATH=/usr/lib/postgresql/${{ inputs.pg-version }}/bin/pg_config \
cargo build --release --no-default-features \
--features pg${{ inputs.pg-version }} \
-p ${{ inputs.extension-crate }}
- name: install .so into postgres service container
shell: bash
run: |
set -euo pipefail
PGLIB=$(docker exec "${{ inputs.postgres-container-id }}" pg_config --pkglibdir)
docker cp \
target/release/${{ inputs.built-so-name }} \
"${{ inputs.postgres-container-id }}:${PGLIB}/${{ inputs.install-so-name }}"
23 changes: 23 additions & 0 deletions .github/actions/setup-rust/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: setup-rust
description: |
Common setup for jobs that need Rust + mise. Caller must run
actions/checkout@v6 before this composite. Pass a distinct cache-key per
job so rust-cache slots do not evict each other (which is the single
biggest source of cold-rebuild waste in the old CI).
inputs:
cache-key:
description: rust-cache shared-key. Use a unique value per job (e.g. lint, rust-test, handoff-test, ts-test, sqlx-check, gen).
required: true
runs:
using: composite
steps:
- uses: jdx/mise-action@v4
with:
cache: true
- name: rustup components
shell: bash
run: rustup component add rustfmt clippy
- uses: Swatinem/rust-cache@v2
with:
shared-key: ${{ inputs.cache-key }}
cache-on-failure: true
182 changes: 117 additions & 65 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,40 @@ on:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
CARGO_TERM_COLOR: always
SQLX_OFFLINE: "false"
DATABASE_URL: postgres://beyond:password@localhost:5432/beyond-auth
jobs:
ci:
lint:
runs-on: ubuntu-latest
env:
SQLX_OFFLINE: "true"
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-rust
with:
cache-key: lint
- run: mise run check:fmt
- run: mise run check:rs
generate-check:
name: generated files up-to-date
runs-on: ubuntu-latest
env:
SQLX_OFFLINE: "true"
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-rust
with:
cache-key: gen
- run: mise run generate:openapi
- run: mise run generate:types
- name: check no diff
run: git diff --exit-code -- openapi/v1.json sdk/ts/src/types.ts sdk/ts/src/react/types.ts
sqlx-check:
name: sqlx offline cache up-to-date
runs-on: ubuntu-latest
services:
postgres:
Expand All @@ -24,71 +52,95 @@ jobs:
--health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
- name: ensure rustfmt/clippy components
run: rustup component add rustfmt clippy
- uses: Swatinem/rust-cache@v2
- name: install postgres 18 dev headers
run: |
sudo apt-get install -y gnupg2 lsb-release
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc \
| sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/pgdg.gpg
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
sudo apt-get install -y postgresql-server-dev-18 libclang-dev clang
- name: build and install authz extension
- uses: ./.github/actions/setup-rust
with:
cache-key: sqlx-check
- uses: ./.github/actions/setup-pgrx
with:
extension-crate: beyond-auth-extension
built-so-name: libbeyond_auth_extension.so
install-so-name: beyond_auth_extension.so
postgres-container-id: ${{ job.services.postgres.id }}
- run: mise run migrate
- run: mise run check:sqlx
rust-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:18
env:
POSTGRES_CONTAINER: ${{ job.services.postgres.id }}
run: |
PGRX_PG_CONFIG_PATH=/usr/lib/postgresql/18/bin/pg_config \
cargo build --release --no-default-features --features pg18 -p beyond-auth-extension
PGLIB=$(docker exec "$POSTGRES_CONTAINER" pg_config --pkglibdir)
docker cp target/release/libbeyond_auth_extension.so \
"${POSTGRES_CONTAINER}:${PGLIB}/beyond_auth_extension.so"
- name: migrate
run: mise run migrate
- name: check:sqlx
# Verify the committed .sqlx/ query cache is in sync with the
# query!/query_as! macro calls in code. Runs after migrate so the
# CI postgres has the schema the macros need to introspect.
run: mise run check:sqlx
- name: check:fmt
run: mise run check:fmt
- name: check:rs
run: mise run check:rs
- name: test:unit:rs
run: mise run test:unit:rs
- name: test:integration:rs
run: mise run test:integration:rs
- name: test:integration:rs:handoff
# End-to-end handoff tests: spawn the real beyond-auth binary +
# bundled handoff-test-supervisor, drive zero-downtime restarts
# under load (including TLS, supervisor crash, multi-cycle abort,
# and slow-drain heartbeat scenarios).
run: mise run test:integration:rs:handoff
- name: check:ts
run: mise run check:ts
- name: build:rs:release
run: mise run build:rs:release
- name: build:ts
run: mise run build:ts
- name: test:integration:ts
POSTGRES_USER: beyond
POSTGRES_PASSWORD: password
POSTGRES_DB: beyond-auth
ports:
- 5432:5432
options: >-
--health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-rust
with:
cache-key: rust-test
- uses: ./.github/actions/setup-pgrx
with:
extension-crate: beyond-auth-extension
built-so-name: libbeyond_auth_extension.so
install-so-name: beyond_auth_extension.so
postgres-container-id: ${{ job.services.postgres.id }}
- run: mise run migrate
- run: mise run test:unit:rs
- run: mise run test:integration:rs
handoff-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:18
env:
BEYOND_AUTH_BINARY: ${{ github.workspace }}/target/release/beyond-auth
run: mise run test:integration:ts
generate-check:
name: generated files up-to-date
POSTGRES_USER: beyond
POSTGRES_PASSWORD: password
POSTGRES_DB: beyond-auth
ports:
- 5432:5432
options: >-
--health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup-rust
with:
cache-key: handoff-test
- uses: ./.github/actions/setup-pgrx
with:
extension-crate: beyond-auth-extension
built-so-name: libbeyond_auth_extension.so
install-so-name: beyond_auth_extension.so
postgres-container-id: ${{ job.services.postgres.id }}
- run: mise run migrate
- run: mise run test:integration:rs:handoff
ts-test:
runs-on: ubuntu-latest
env:
SQLX_OFFLINE: "true"
services:
postgres:
image: postgres:18
env:
POSTGRES_USER: beyond
POSTGRES_PASSWORD: password
POSTGRES_DB: beyond-auth
ports:
- 5432:5432
options: >-
--health-cmd pg_isready --health-interval 5s --health-timeout 5s --health-retries 5
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
- name: ensure rustfmt/clippy components
run: rustup component add rustfmt clippy
- uses: Swatinem/rust-cache@v2
- name: generate
run: mise run generate:openapi && mise run generate:types
- name: check no diff
run: git diff --exit-code -- openapi/v1.json sdk/ts/src/types.ts
- uses: ./.github/actions/setup-rust
with:
cache-key: ts-test
- uses: ./.github/actions/setup-pgrx
with:
extension-crate: beyond-auth-extension
built-so-name: libbeyond_auth_extension.so
install-so-name: beyond_auth_extension.so
postgres-container-id: ${{ job.services.postgres.id }}
- run: mise run migrate
- run: mise run check:ts
- run: mise run build:ts
- run: mise run test:integration:ts
29 changes: 29 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Security
on:
schedule:
# Mondays 14:00 UTC. Weekly cadence — real advisory churn, not per-push theater.
- cron: "0 14 * * 1"
workflow_dispatch:
permissions:
contents: read
issues: write
jobs:
cargo-deny:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: EmbarkStudios/cargo-deny-action@v2
id: deny
with:
command: check advisories licenses bans sources
arguments: --workspace --all-features
- name: open regression issue
if: failure()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
gh issue create \
--title "cargo-deny regression ($(date -u +%Y-%m-%d))" \
--label security,automation \
--body "Weekly cargo-deny found a new advisory/license/ban/source issue. Run: $RUN_URL"
55 changes: 55 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# cargo-deny config. Scoped weekly via .github/workflows/security.yml.
# Not run on PR — that was the cargo-audit theater this replaces. Real
# regressions open a GitHub issue.

[graph]
all-features = true

[advisories]
version = 2
yanked = "deny"
ignore = [
# sqlx unconditionally resolves sqlx-mysql in its proc-macro crate
# (sqlx-macros-core) even when only the postgres feature is enabled. We
# don't use MySQL and rsa is never compiled into the binary. No fix is
# available upstream. Migrated from .cargo/audit.toml.
{ id = "RUSTSEC-2023-0071", reason = "sqlx-macros-core pulls in sqlx-mysql/rsa transitively; postgres-only build, no fix upstream" },
]

[licenses]
version = 2
# Permissive licenses allowed across the workspace + transitive deps.
allow = [
"MIT",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Unicode-3.0",
"Unicode-DFS-2016",
"Zlib",
"MPL-2.0",
"CC0-1.0",
"0BSD",
"BSL-1.0",
]
confidence-threshold = 0.8
unused-allowed-license = "allow"
# Weak-copyleft / corporate-unfriendly licenses are denied by omission from
# `allow`. Per-crate exceptions (e.g. ring's BoringSSL bits) go in `exceptions`.
exceptions = []

[bans]
multiple-versions = "allow"
wildcards = "allow"
# Populate when concrete bans are decided (e.g. ban openssl<0.10, tokio<1).
deny = []
skip = []
skip-tree = []

[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
6 changes: 5 additions & 1 deletion mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ run = "cargo sqlx prepare --check --workspace -- --tests --features test-server"
[tasks."test:integration:ts"]
run = "npm test"
dir = "sdk/ts"
depends = ["generate:types", "build:rs", "test:integration:rs"]
# test:integration:rs is intentionally NOT a dep here: in CI it gets run
# in its own job already, and re-running it as a dep here cost ~3–6m of
# duplicate compile+test. Local devs who want defensive ordering can run
# `mise run test:integration:rs && mise run test:integration:ts`.
depends = ["generate:types", "build:rs"]

[tasks."generate:openapi"]
run = "cargo run -- generate-openapi"
Expand Down
Loading