add MCP #44
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: CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| DATABASE_URL: postgres://agentauth:agentauth_dev@localhost:5434/agentauth | |
| DATABASE_REPLICA_URL: postgres://agentauth:agentauth_dev@localhost:5435/agentauth | |
| REDIS_URL: redis://localhost:6379 | |
| jobs: | |
| rust-checks: | |
| name: Rust Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy, rustfmt | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| - name: Cache cargo binaries | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cargo/bin | |
| key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/ci.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-bin- | |
| - name: Install cargo tools | |
| run: | | |
| # Only install if not already cached | |
| command -v cargo-nextest >/dev/null 2>&1 || cargo install cargo-nextest --locked | |
| command -v cargo-audit >/dev/null 2>&1 || cargo install cargo-audit --locked | |
| command -v cargo-deny >/dev/null 2>&1 || cargo install cargo-deny --locked | |
| - name: Check workspace | |
| run: cargo check --workspace | |
| - name: Clippy | |
| run: cargo clippy --workspace -- -D warnings | |
| - name: Security audit | |
| run: cargo audit | |
| - name: License and dependency check | |
| run: | | |
| cargo deny check licenses || echo "::warning::License check not configured" | |
| cargo deny check bans || echo "::warning::Ban check not configured" | |
| integration-tests: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| needs: rust-checks | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: agentauth | |
| POSTGRES_PASSWORD: agentauth_dev | |
| POSTGRES_DB: agentauth | |
| ports: | |
| - 5434:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| - name: Cache cargo binaries | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cargo/bin | |
| key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/ci.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-bin- | |
| - name: Install cargo tools | |
| run: | | |
| # Only install if not already cached | |
| command -v cargo-nextest >/dev/null 2>&1 || cargo install cargo-nextest --locked | |
| command -v sqlx >/dev/null 2>&1 || cargo install sqlx-cli --locked --no-default-features --features postgres | |
| - name: Run migrations | |
| run: | | |
| sqlx migrate run --source migrations/ || echo "::warning::No migrations found" | |
| - name: Test migration rollback | |
| run: | | |
| sqlx migrate revert --source migrations/ || echo "::warning::No migrations to revert" | |
| sqlx migrate run --source migrations/ || echo "::warning::No migrations found" | |
| - name: Run tests | |
| run: cargo nextest run --workspace | |
| - name: Run compliance tests | |
| run: cargo nextest run --test compliance || echo "::warning::No compliance tests found" | |
| security-patterns: | |
| name: Security Pattern Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Check for plaintext key backends in production code | |
| run: | | |
| # Check for InMemorySigningBackend outside of #[cfg(test)] blocks | |
| # The struct and impl are properly gated with #[cfg(test)] in backend.rs | |
| # We check that no service code uses it | |
| if grep -rn "InMemorySigningBackend" services/ --include="*.rs" | grep -v "//"; then | |
| echo "::error::Found InMemorySigningBackend in service code" | |
| exit 1 | |
| fi | |
| # Check for PlaintextKeyfile feature in production Dockerfiles and Helm charts | |
| # PlaintextKeyfile is gated behind allow-plaintext-keys feature | |
| if grep -rn "allow-plaintext-keys" Dockerfile* deploy/ --include="*.yml" --include="*.yaml" 2>/dev/null; then | |
| echo "::error::Found allow-plaintext-keys feature in production configs" | |
| exit 1 | |
| fi | |
| echo "No plaintext key backends found in production code" | |
| - name: Check for unwrap() in library crates | |
| run: | | |
| # Count unwraps in non-test code (warning only for now) | |
| count=$(grep -rn "\.unwrap()" crates/ --include="*.rs" | grep -v "#\[cfg(test)\]\|//.*safe because\|test::" | wc -l) | |
| if [ "$count" -gt 0 ]; then | |
| echo "::warning::Found $count uses of unwrap() in library crates" | |
| grep -rn "\.unwrap()" crates/ --include="*.rs" | grep -v "#\[cfg(test)\]\|//.*safe because\|test::" | head -20 | |
| fi | |
| - name: Check for hardcoded secrets | |
| run: | | |
| if grep -rn "secret\|password\|private_key\|api_key" crates/ services/ --include="*.rs" | grep -v "//\|\"\"" | grep "= \"" | grep -v "test\|example\|placeholder"; then | |
| echo "::error::Potential hardcoded secrets found" | |
| exit 1 | |
| fi | |
| echo "No hardcoded secrets found" | |
| - name: Check for SQL string interpolation | |
| run: | | |
| # Match DML patterns only (SELECT FROM, INSERT INTO, UPDATE SET, DELETE FROM). | |
| # GRANT/REVOKE DDL in partition.rs uses format! with internally-generated | |
| # partition names (not user input) and is intentionally excluded. | |
| if grep -rn "format!.*SELECT.*FROM\|format!.*INSERT.*INTO\|format!.*UPDATE.*SET\|format!.*DELETE FROM" crates/ services/ --include="*.rs"; then | |
| echo "::error::SQL string interpolation found - use parameterized queries" | |
| exit 1 | |
| fi | |
| echo "No SQL string interpolation found" | |
| docs: | |
| name: Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| - name: Build documentation | |
| run: cargo doc --no-deps --workspace | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| load-test: | |
| name: Load Test Baseline | |
| runs-on: ubuntu-latest | |
| needs: integration-tests | |
| if: github.ref == 'refs/heads/main' | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: agentauth | |
| POSTGRES_PASSWORD: agentauth_dev | |
| POSTGRES_DB: agentauth | |
| ports: | |
| - 5434:5432 | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| redis: | |
| image: redis:7-alpine | |
| ports: | |
| - 6379:6379 | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install k6 | |
| run: | | |
| sudo gpg -k | |
| sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69 | |
| echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list | |
| sudo apt-get update | |
| sudo apt-get install k6 | |
| - name: Run load tests | |
| run: | | |
| if [ -f "load-tests/token-verify.js" ]; then | |
| k6 run --vus 10 --duration 30s load-tests/token-verify.js | |
| else | |
| echo "::warning::No load tests found" | |
| fi | |
| ci-success: | |
| name: CI Success | |
| runs-on: ubuntu-latest | |
| needs: [rust-checks, integration-tests, security-patterns, docs] | |
| if: always() | |
| steps: | |
| - name: Check all jobs passed | |
| run: | | |
| if [ "${{ needs.rust-checks.result }}" != "success" ] || \ | |
| [ "${{ needs.integration-tests.result }}" != "success" ] || \ | |
| [ "${{ needs.security-patterns.result }}" != "success" ] || \ | |
| [ "${{ needs.docs.result }}" != "success" ]; then | |
| echo "One or more jobs failed" | |
| exit 1 | |
| fi | |
| echo "All CI checks passed!" |