Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
188 commits
Select commit Hold shift + click to select a range
f32e7a5
feat: improve security lab tests coverage
Bulletdev Apr 11, 2026
91b7a62
fix: solve scrims public lobby display
Bulletdev Apr 11, 2026
5bb446b
chore: adjust dependencies
Bulletdev Apr 11, 2026
bcff9b9
feat: implement schedule audit
Bulletdev Apr 12, 2026
23e04f2
feat: implement tournments module
Bulletdev Apr 12, 2026
1a1c715
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 12, 2026
8364690
fix: solve snyk issue
Bulletdev Apr 12, 2026
df7b939
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 12, 2026
5750632
fix: solve hash id issue
Bulletdev Apr 12, 2026
aa3527b
fix: remove unused dependencies
Bulletdev Apr 12, 2026
756d021
fix: solve pro matches issue
Bulletdev Apr 12, 2026
33c78d8
fix: solve tournment bracket issues
Bulletdev Apr 12, 2026
a8c3b38
feat: add team tag to organizations
Bulletdev Apr 12, 2026
4f3a900
fix: solve nightly workflow run issue
Bulletdev Apr 13, 2026
1c34eaa
fix: solve bundler mismatch
Bulletdev Apr 13, 2026
d13d900
fix: solve tournment bracket rules
Bulletdev Apr 13, 2026
e719b25
fix: solve remainig nightly workflow issues
Bulletdev Apr 14, 2026
52d0776
chore: adjust bracket generator rule
Bulletdev Apr 14, 2026
6ff1a6e
feat: improve connection pooling
Bulletdev Apr 14, 2026
93a5e15
Remove duplicate badges in README.md
Bulletdev Apr 14, 2026
915bab3
feat: implement database test
Bulletdev Apr 15, 2026
ac72fa2
feat: implement tier thresholds
Bulletdev Apr 15, 2026
ef873d9
chore: bump version to ruby 3.4.9
Bulletdev Apr 15, 2026
1d31af1
chore: bump version to ruby 3.4.8
Bulletdev Apr 15, 2026
eb0768a
feat: implement target season history
Bulletdev Apr 15, 2026
e677899
chore: Update database description
Bulletdev Apr 16, 2026
6df5dc7
feat: implement CircuitBreaker + cache layer
Bulletdev Apr 16, 2026
fbdee77
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 16, 2026
c8e2420
chore: adjust api call to load test scenario
Bulletdev Apr 17, 2026
cd81471
chore: use local database instead serverless
Bulletdev Apr 17, 2026
6c85174
chore: adjust database conection
MichaelPlathanus Apr 17, 2026
c3fd972
fix: solve sidekiq major outage
MichaelPlathanus Apr 17, 2026
e14a8d3
feat: implement go riot proxy
Bulletdev Apr 18, 2026
5938c6b
fix: solve mismatch into sync matchs
Bulletdev Apr 18, 2026
4777365
fix: solve zeitwrk issue into import matches
Bulletdev Apr 18, 2026
f681444
fix: solve heartbeat issue
Bulletdev Apr 18, 2026
532c183
feat: add discord duplicated warning
Bulletdev Apr 18, 2026
4b3fa4a
feat: implement gateway into api workflow
Bulletdev Apr 18, 2026
98579da
fix: solve matches scope mismatch
Bulletdev Apr 18, 2026
cc30950
fix: solve internal schema issue
Bulletdev Apr 18, 2026
b373938
fix: solve migrations issue
Bulletdev Apr 18, 2026
bdf68ee
fix: adjust schema idempotency
Bulletdev Apr 18, 2026
fc46268
chore: improve code style
Bulletdev Apr 18, 2026
af4dcc8
chore: adjust rack attack by ip address
Bulletdev Apr 18, 2026
1a91333
feat: implement mailing and templates
Bulletdev Apr 18, 2026
fb034cc
chore: adjust license and cookbooks
Bulletdev Apr 20, 2026
10cd6f4
feat: implement pandascore
Bulletdev Apr 20, 2026
157306d
chore: adjust gateway integration
Bulletdev Apr 20, 2026
ffb9dc1
chore: improve build cache
Bulletdev Apr 20, 2026
386d619
feat: implement aud into payload
Bulletdev Apr 20, 2026
5db6727
feat: implement multi roster
Bulletdev Apr 20, 2026
5c594c3
fix: solve migrations entrypoint
Bulletdev Apr 20, 2026
e994cd3
fix: solve sidekiq healthcheck
Bulletdev Apr 20, 2026
e690232
refactor: solve team comparison gaps
Bulletdev Apr 20, 2026
de51a9b
fix: solve period issue into comparison
Bulletdev Apr 20, 2026
489e168
fix: solve unscoped player issue
Bulletdev Apr 20, 2026
6c7ccfe
fix: adjust player policy
Bulletdev Apr 20, 2026
eebdf8a
fix: solve org unscoped minor issue
Bulletdev Apr 20, 2026
36533c8
fix: solve database port mapping
Bulletdev Apr 20, 2026
af2e2ff
chore: improve match details
Bulletdev Apr 20, 2026
92f8056
fix: solve import to roster issue
Bulletdev Apr 21, 2026
30f48cb
fix: solve player import to roster issue
Bulletdev Apr 21, 2026
a8d0ff5
refactor: extract MatchFilterQuery, cache invalidation, and security …
Bulletdev Apr 21, 2026
d0e4d29
chore: improve api docs page
Bulletdev Apr 22, 2026
a86f474
fix: solve smtp issue and dead jobs
Bulletdev Apr 22, 2026
8ab352e
fix: solve scraper match index issue
Bulletdev Apr 22, 2026
ce55112
fix: solve healthcheck minor issue
Bulletdev Apr 22, 2026
5488b27
fix: solve semgrep issues
Bulletdev Apr 22, 2026
64b9b63
feat: implement prostaff events
Bulletdev Apr 22, 2026
2084e35
fix: solve req and telemetry issues
Bulletdev Apr 22, 2026
04f0d9d
feat: implement pro match details
Bulletdev Apr 23, 2026
8ba32a8
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 23, 2026
9503d2d
docs: improve readability
Bulletdev Apr 23, 2026
ad6cae5
docs: update architecture and dataflow
Bulletdev Apr 23, 2026
11b77f9
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 23, 2026
f7d7db4
fix: solve scouting waitlist issue
Bulletdev Apr 23, 2026
76e0efe
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 23, 2026
b369f3f
feat: implement observability
Bulletdev Apr 23, 2026
9e00b47
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 23, 2026
d641764
docs: update changelog
Bulletdev Apr 23, 2026
1e59933
fix: solve filebeat issue
Bulletdev Apr 23, 2026
a2c5dcb
fix: solve single-query no vector builder.
Bulletdev Apr 23, 2026
5b06c37
fix: solve exact match mismatch
Bulletdev Apr 23, 2026
ca565da
chore: adjust allowed host
Bulletdev Apr 23, 2026
0238774
fix: solve sidekiq admin minor issue
Bulletdev Apr 23, 2026
e4fd358
fix: sidekiq session issue
Bulletdev Apr 23, 2026
30cb782
fix: solve rack session issue
Bulletdev Apr 23, 2026
6dabafe
chore: adjust sidekiq bypass
Bulletdev Apr 23, 2026
33fd6a0
fix: solve sidekiq allowed content
Bulletdev Apr 23, 2026
252b822
fix: solve aditional sidekiq csp
Bulletdev Apr 23, 2026
08ac810
fix: solve CSP mismatch for sidekiq
Bulletdev Apr 24, 2026
12e6edb
fix: solve atomic conflict
Bulletdev Apr 24, 2026
0b817d6
fix: solve setlocal mismatch and upsert
Bulletdev Apr 24, 2026
b822156
docs: update service links and add observability details
Bulletdev Apr 24, 2026
deb6b7e
fix: solve pro matches card issues
Bulletdev Apr 24, 2026
747986d
docs: Refactor architecture section in README
Bulletdev Apr 24, 2026
22ff842
docs: enhance deployment architecture
Bulletdev Apr 24, 2026
8885c10
docs: revise competitive module details and formatting
Bulletdev Apr 24, 2026
6a0447b
feat: implement ProStaff ML
Bulletdev Apr 24, 2026
5fbd44d
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 24, 2026
e75b0d5
docs: update to insert ML service
Bulletdev Apr 24, 2026
3794362
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 24, 2026
e4ba820
fix: solve map ML suggestions issue
Bulletdev Apr 25, 2026
49c978b
docs: add Scraper API and related components
Bulletdev Apr 25, 2026
749fd48
docs: Update enrichment descriptions
Bulletdev Apr 25, 2026
d171cbd
docs: update README with Mermaid Live Editor link
Bulletdev Apr 25, 2026
ad06e94
Update README.md
Bulletdev Apr 26, 2026
98f64f0
fix: solve BackfillJob issue
Bulletdev Apr 26, 2026
e89c213
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 26, 2026
f7fc3d4
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 26, 2026
83d9ebd
feat: add competitive name into org
Bulletdev Apr 26, 2026
abd7209
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 26, 2026
b792ddf
chore(deps): bump erb from 6.0.2 to 6.0.4 (#31)
dependabot[bot] Apr 26, 2026
844ce6e
docs: Update service links in README.md
Bulletdev Apr 26, 2026
58927f0
docs: remove duplicated module architecture details
Bulletdev Apr 26, 2026
cd53cce
docs: Fix formatting of project entries
Bulletdev Apr 26, 2026
83e05fa
feat: implement team chat
Bulletdev Apr 26, 2026
536ac24
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 26, 2026
96f01eb
chore: add FK to avoid conflict
Bulletdev Apr 26, 2026
da6c1b1
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 26, 2026
8122b8a
fix: solve database mismatch
Bulletdev Apr 26, 2026
dc4921f
fix: solve FK issue
Bulletdev Apr 26, 2026
d4fa09c
chore: adjust test scheme
Bulletdev Apr 26, 2026
aa7fa6d
fix: solve team chat websocket issue
Bulletdev Apr 27, 2026
b081894
fix: solve messaging channel
Bulletdev Apr 27, 2026
73fe16c
docs: simplify architecture section
Bulletdev Apr 27, 2026
4b71fbc
fix: solve promatches paginations issue
Bulletdev Apr 27, 2026
46cd98e
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 27, 2026
865e61c
docs: simplify architecture section
Bulletdev Apr 27, 2026
d7e31d9
fix: solve promatches search issue
Bulletdev Apr 27, 2026
c930f88
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 27, 2026
0e70be9
fix: solve promatches search issue
Bulletdev Apr 27, 2026
251902e
Refactor README to eliminate redundancy
Bulletdev Apr 27, 2026
be20ecd
feat: implement draft simulator
Bulletdev Apr 28, 2026
33940f6
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 28, 2026
bf1a33a
docs: auto-update architecture diagram [skip ci]
github-actions[bot] Apr 28, 2026
ba8ef1e
fix: solve semgrep inline issues
Bulletdev Apr 28, 2026
f78de58
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev Apr 28, 2026
2fda2cb
fix: solve semgrep deploy alert
Bulletdev Apr 28, 2026
39ad326
fix: solve Zeitwerk module nesting
Bulletdev Apr 28, 2026
e2f282a
fix: solve array render into draft
Bulletdev Apr 28, 2026
6b18fa0
docs: Refactor architecture section in README.md
Bulletdev Apr 29, 2026
03cd195
fix: solve scrims lobby issue
Bulletdev Apr 29, 2026
c07c8f2
refactor: remove fantasy feature
Bulletdev May 3, 2026
fe4ae74
feat: implement monitoring sources
Bulletdev May 3, 2026
5a57ee5
feat: implement payment gateway
Bulletdev May 6, 2026
523815b
fix: solve dependency issue
Bulletdev May 7, 2026
63cbc70
fix: solve analytics dashboard issues
Bulletdev May 8, 2026
05c5caf
fix: solve linter issues
Bulletdev May 8, 2026
856235c
fix: solve stack trace audit
Bulletdev May 8, 2026
8634641
fix: update hostname whitelist
Bulletdev May 8, 2026
cd58fb0
fix: solve dropdown override into docs
Bulletdev May 8, 2026
5092983
feat: implement monitoring templates
Bulletdev May 8, 2026
b98ef87
fix: solve script runtime
Bulletdev May 8, 2026
645c404
feat: implement monitoring service
Bulletdev May 8, 2026
d8205c6
feat: implement monitoring alert manager
Bulletdev May 8, 2026
4955641
chore: adjust codacy rules
Bulletdev May 8, 2026
2a37d05
chore(deps): bump net-imap from 0.6.3 to 0.6.4 (#32)
dependabot[bot] May 8, 2026
25918f5
fix: solve alert manager issue
Bulletdev May 8, 2026
9b14c68
Merge branch 'master' of https://github.com/Bulletdev/prostaff-api
Bulletdev May 8, 2026
d76ba49
fix: solve ChampionWinrateService missing data
Bulletdev May 8, 2026
0d5defe
fix: solve team mismatch
Bulletdev May 8, 2026
00fed62
feat: implement riot heartbeat
Bulletdev May 11, 2026
d6e7f31
chore: bump nokogiri to 1.19.3
Bulletdev May 11, 2026
3911322
feat: implement fingertips to competitive
Bulletdev May 12, 2026
aae390e
refactor: solve code style and minor issues
Bulletdev May 12, 2026
1e36c3b
fix: solve fingertip concern issue
Bulletdev May 12, 2026
c3667b8
fix: solve match fingerprint mismatch
Bulletdev May 12, 2026
aeec607
chore: add codacy into branch ruleset
Bulletdev May 12, 2026
e3f9a4a
fix: solve patch sort and side win mismatch
Bulletdev May 12, 2026
0370223
fix: solve side win /lose mismatch
Bulletdev May 12, 2026
4bd7eea
feat: implement draft lobby
Bulletdev May 12, 2026
a61fad9
feat: implement delet lobby resource
Bulletdev May 12, 2026
5334dbc
test: improve coverage
Bulletdev May 12, 2026
a762568
feat: implement wallet 4 ArenaBR
Bulletdev May 17, 2026
49630b9
fix: solve Docker Hub timeout
Bulletdev May 17, 2026
1f8f4c9
fix: ensure ProPay customer exists before proxying wallet deposit
Bulletdev May 17, 2026
fffd37e
fix: solve error handler 4 pix
Bulletdev May 17, 2026
d7f4780
feat(auth): migrate password hashing from bcrypt to Argon2id
Bulletdev May 19, 2026
e22f3b9
fix: Gemfile & Gemfile.lock to reduce vulnerabilities
snyk-bot May 19, 2026
4340fa7
chore: bump jwt and faraday versions
Bulletdev May 19, 2026
6f4b11d
Merge branch 'master' into snyk-fix-bf66c213615e5e1d63d274137092017c
MichaelPlathanus May 19, 2026
71bb62c
fix(security): patch jwt and faraday CVEs reported by Snyk
MichaelPlathanus May 19, 2026
a195261
fix(auth): fail fast on blank JWT key + libargon2-dev in Dockerfile
Bulletdev May 19, 2026
c13ee68
Merge remote-tracking branch 'origin/master'
Bulletdev May 19, 2026
092a118
fix(argon2): correct m_cost from absolute KiB to exponent
Bulletdev May 19, 2026
c3f93fe
test(auth): add argon2id migration specs and fix Player password vali…
Bulletdev May 20, 2026
2f8dd90
test(auth): harden test DB guard to cover TEST_DATABASE_URL and poole…
Bulletdev May 20, 2026
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: 5 additions & 0 deletions .codacy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,8 @@ exclude_paths:
# payloads like '$MONGO_GT' and '`id`' must NOT expand. SC2034 (BASE_URL) is used
# further down in the same script.
- ".pentest/**"

# Monitoring infrastructure templates — SMTP environment variable references
# in docker-compose look like credentials to static scanners. alertmanager.yml
# is gitignored (only .example is tracked).
- "docker-compose.monitoring.yml"
25 changes: 25 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,31 @@ SCRAPER_API_URL=https://scraper.prostaff.gg
# Must match SCRAPER_API_KEY configured on the scraper service
SCRAPER_API_KEY=

# ===========================================
# prostaff-events Integration (Phoenix event bus)
# ===========================================
# Real-time WebSocket hub and event bus. Rails publishes domain events to Redis
# pub/sub (channel: prostaff:events:<org_id>), Phoenix subscribes and broadcasts
# to connected frontend clients.
#
# Leave blank to disable event publishing (events are silently dropped).
# When set, Events::EventPublisher will publish to Redis on every domain event.
#
# Internal JWT secret shared with prostaff-events for service-to-service auth.
# Must match INTERNAL_JWT_SECRET configured in prostaff-events.
PHOENIX_EVENTS_ENABLED=false
PHOENIX_EVENTS_URL=http://localhost:4000
INTERNAL_JWT_SECRET=

# ===========================================
# Sidekiq Web UI (production access)
# ===========================================
# Credentials for /sidekiq dashboard (HTTP Basic Auth).
# Both must be set — UI stays inaccessible if either is blank (safe default).
# Generate password: openssl rand -hex 32
SIDEKIQ_WEB_USER=
SIDEKIQ_WEB_PASSWORD=

# ===========================================
# HashID Configuration (for public URL obfuscation)
# ===========================================
Expand Down
4 changes: 4 additions & 0 deletions .github/branch-protection-ruleset.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
{
"context": "Security Scan",
"integration_id": null
},
{
"context": "codacy/pr-quality-review",
"integration_id": null
}
],
"strict_required_status_checks_policy": true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ new-feature-test:
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4.5
ruby-version: 3.4.8
bundler-cache: true
- name: Setup Database
run: bundle exec rails db:migrate RAILS_ENV=test
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ on:

permissions:
security-events: write # upload SARIF para o Security tab
pull-requests: write # postar comentario de resumo no PR
packages: read
actions: read
contents: read
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # v1
with:
ruby-version: 3.4.5
ruby-version: 3.4.8
bundler-cache: true

- name: Install dependencies
Expand Down Expand Up @@ -236,7 +236,7 @@ jobs:

steps:
- name: Manual approval checkpoint
run: |
run: | # nosemgrep: yaml.github-actions.security.run-shell-injection.run-shell-injection
echo "=================================="
echo "🚨 PRODUCTION DEPLOYMENT"
echo "=================================="
Expand Down Expand Up @@ -511,7 +511,7 @@ jobs:
fi

- name: Display notification
run: |
run: | # nosemgrep: yaml.github-actions.security.run-shell-injection.run-shell-injection
echo "=============================================="
echo "${{ env.STATUS }}"
echo "${{ env.MESSAGE }}"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # v1
with:
ruby-version: 3.4.5
ruby-version: 3.4.8
bundler-cache: true

- name: Install dependencies
Expand Down Expand Up @@ -262,7 +262,7 @@ jobs:
fi

- name: Display notification
run: |
run: | # nosemgrep: yaml.github-actions.security.run-shell-injection.run-shell-injection
echo "======================================"
echo "${{ env.STATUS }}"
echo "${{ env.MESSAGE }}"
Expand Down
166 changes: 88 additions & 78 deletions .github/workflows/nightly-security.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
name: Nightly Security Audit

on:
# TODO: Reativar quando em produção
# schedule:
# # Run every night at 1am UTC
# - cron: '0 1 * * *'
schedule:
# Run every night at 1am UTC
- cron: '0 1 * * *'
workflow_dispatch:

permissions:
Expand All @@ -15,6 +14,8 @@ jobs:
full-security-audit:
name: Complete Security Audit
runs-on: ubuntu-latest
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
services:
postgres:
image: postgres:14
Expand Down Expand Up @@ -46,38 +47,40 @@ jobs:
- name: Set up Ruby
uses: ruby/setup-ruby@09a7688d3b55cf0e976497ff046b70949eeaccfd # v1
with:
ruby-version: 3.4.5
ruby-version: 3.4.8
bundler-cache: true

- name: Setup Database
env:
RAILS_ENV: test
DATABASE_URL: postgres://postgres:postgres@localhost:5432/prostaff_test
TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/prostaff_test
REDIS_URL: redis://localhost:6379/0
SECRET_KEY_BASE: nightly_audit_secret_key_base_not_for_production
JWT_SECRET_KEY: nightly_audit_jwt_secret_not_for_production
run: |
bundle exec rails db:create
bundle exec rails db:migrate

- name: Start Rails Server
env:
RAILS_ENV: test
DATABASE_URL: postgres://postgres:postgres@localhost:5432/prostaff_test
TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/prostaff_test
REDIS_URL: redis://localhost:6379/0
SECRET_KEY_BASE: nightly_audit_secret_key_base_not_for_production
JWT_SECRET_KEY: nightly_audit_jwt_secret_not_for_production
run: |
bundle exec rails server -p 3333 -e test &
sleep 10
curl -f http://localhost:3333/up || exit 1
bundle exec rails server -p 3333 -e test -d
timeout 60 bash -c 'until curl -sf http://localhost:3333/up; do sleep 2; done'

- name: Install Security Tools
run: |
gem install brakeman bundler-audit
docker pull zaproxy/zap-stable
- name: Install ZAP
run: docker pull zaproxy/zap-stable

- name: Create Reports Directory
run: mkdir -p security_tests/reports/nightly

- name: Run Brakeman
run: |
brakeman --rails7 \
bundle exec brakeman --rails7 \
--format json \
--output security_tests/reports/nightly/brakeman.json \
--format html \
Expand All @@ -86,13 +89,18 @@ jobs:

- name: Run Bundle Audit
run: |
bundle-audit update
bundle-audit check > security_tests/reports/nightly/bundle-audit.txt || true
bundle exec bundler-audit update
bundle exec bundler-audit check \
--format json \
--output security_tests/reports/nightly/bundle-audit.json \
|| true
# Also write plain text for human readability
bundle exec bundler-audit check > security_tests/reports/nightly/bundle-audit.txt || true

- name: Run ZAP Baseline Scan
run: |
docker run --rm --network="host" \
-v $(pwd)/security_tests/reports/nightly:/zap/wrk:rw \
-v "$(pwd)/security_tests/reports/nightly:/zap/wrk:rw" \
zaproxy/zap-stable \
zap-baseline.py \
-t http://localhost:3333 \
Expand All @@ -102,10 +110,10 @@ jobs:
- name: Run ZAP API Scan
run: |
docker run --rm --network="host" \
-v $(pwd)/security_tests/reports/nightly:/zap/wrk:rw \
-v "$(pwd)/security_tests/reports/nightly:/zap/wrk:rw" \
zaproxy/zap-stable \
zap-api-scan.py \
-t http://localhost:3333/api-docs/v1/swagger.json \
-t http://localhost:3333/api-docs/v1/swagger.yaml \
-f openapi \
-r zap-api.html \
-J zap-api.json || true
Expand All @@ -114,114 +122,116 @@ jobs:
id: parse
run: |
# Brakeman
BRAKEMAN_HIGH=$(jq '[.warnings[] | select(.confidence == "High")] | length' security_tests/reports/nightly/brakeman.json)
BRAKEMAN_TOTAL=$(jq '.warnings | length' security_tests/reports/nightly/brakeman.json)
BRAKEMAN_HIGH=$(jq '[.warnings[] | select(.confidence == "High")] | length' \
security_tests/reports/nightly/brakeman.json 2>/dev/null || echo "0")
BRAKEMAN_TOTAL=$(jq '.warnings | length' \
security_tests/reports/nightly/brakeman.json 2>/dev/null || echo "0")

# Bundle Audit
if grep -q "Vulnerabilities found" security_tests/reports/nightly/bundle-audit.txt; then
if grep -q "Vulnerabilities found" security_tests/reports/nightly/bundle-audit.txt 2>/dev/null; then
VULNERABILITIES="true"
else
VULNERABILITIES="false"
fi

# ZAP
ZAP_HIGH=$(jq '[.site[0].alerts[] | select(.riskcode == "3")] | length' security_tests/reports/nightly/zap-baseline.json 2>/dev/null || echo "0")
ZAP_MEDIUM=$(jq '[.site[0].alerts[] | select(.riskcode == "2")] | length' security_tests/reports/nightly/zap-baseline.json 2>/dev/null || echo "0")
ZAP_HIGH=$(jq '[.site[0].alerts[] | select(.riskcode == "3")] | length' \
security_tests/reports/nightly/zap-baseline.json 2>/dev/null || echo "0")
ZAP_MEDIUM=$(jq '[.site[0].alerts[] | select(.riskcode == "2")] | length' \
security_tests/reports/nightly/zap-baseline.json 2>/dev/null || echo "0")

echo "brakeman_high=$BRAKEMAN_HIGH" >> $GITHUB_OUTPUT
echo "brakeman_total=$BRAKEMAN_TOTAL" >> $GITHUB_OUTPUT
echo "vulnerabilities=$VULNERABILITIES" >> $GITHUB_OUTPUT
echo "zap_high=$ZAP_HIGH" >> $GITHUB_OUTPUT
echo "zap_medium=$ZAP_MEDIUM" >> $GITHUB_OUTPUT
echo "brakeman_high=$BRAKEMAN_HIGH" >> "$GITHUB_OUTPUT"
echo "brakeman_total=$BRAKEMAN_TOTAL" >> "$GITHUB_OUTPUT"
echo "vulnerabilities=$VULNERABILITIES" >> "$GITHUB_OUTPUT"
echo "zap_high=$ZAP_HIGH" >> "$GITHUB_OUTPUT"
echo "zap_medium=$ZAP_MEDIUM" >> "$GITHUB_OUTPUT"

- name: Generate Summary
if: always()
run: |
cat > security_tests/reports/nightly/SUMMARY.md << EOF
# Nightly Security Audit Summary

**Date:** $(date)
**Run:** #${{ github.run_number }}
cat >> "$GITHUB_STEP_SUMMARY" << EOF
# Nightly Security Audit — $(date -u '+%Y-%m-%d %H:%M UTC')

## Results
## Brakeman (SAST)
- Total warnings: ${{ steps.parse.outputs.brakeman_total }}
- High confidence: ${{ steps.parse.outputs.brakeman_high }}

### Brakeman (Code Security)
- Total Warnings: ${{ steps.parse.outputs.brakeman_total }}
- High Confidence: ${{ steps.parse.outputs.brakeman_high }}

### Bundle Audit (Dependencies)
## Bundle Audit (CVEs)
- Vulnerabilities: ${{ steps.parse.outputs.vulnerabilities }}

### OWASP ZAP (Runtime Security)
- High Risk: ${{ steps.parse.outputs.zap_high }}
- Medium Risk: ${{ steps.parse.outputs.zap_medium }}
## OWASP ZAP (DAST)
- High risk: ${{ steps.parse.outputs.zap_high }}
- Medium risk: ${{ steps.parse.outputs.zap_medium }}

## Status

$(if [ "${{ steps.parse.outputs.brakeman_high }}" -gt "0" ] || [ "${{ steps.parse.outputs.vulnerabilities }}" == "true" ] || [ "${{ steps.parse.outputs.zap_high }}" -gt "0" ]; then
echo "⚠️ **ACTION REQUIRED:** Critical security issues detected!"
$(if [ "${{ steps.parse.outputs.brakeman_high }}" -gt "0" ] \
|| [ "${{ steps.parse.outputs.vulnerabilities }}" = "true" ] \
|| [ "${{ steps.parse.outputs.zap_high }}" -gt "0" ]; then
echo "⚠️ **ACTION REQUIRED — critical security issues detected!**"
else
echo "✅ No critical security issues found."
echo "✅ No critical issues found."
fi)

## Reports

- [Brakeman HTML Report](brakeman.html)
- [ZAP Baseline Report](zap-baseline.html)
- [ZAP API Report](zap-api.html)
- [Bundle Audit Report](bundle-audit.txt)
EOF

- name: Job Summary
if: always()
run: |
cat security_tests/reports/nightly/SUMMARY.md >> $GITHUB_STEP_SUMMARY

- name: Upload Reports
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: nightly-security-reports-${{ github.run_number }}
path: security_tests/reports/nightly/
retention-days: 30

- name: Create GitHub Issue on Failure
if: steps.parse.outputs.brakeman_high > 0 || steps.parse.outputs.vulnerabilities == 'true' || steps.parse.outputs.zap_high > 0
if: >
steps.parse.outputs.brakeman_high > 0 ||
steps.parse.outputs.vulnerabilities == 'true' ||
steps.parse.outputs.zap_high > 0
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
with:
script: |
const fs = require('fs');
const summary = fs.readFileSync('security_tests/reports/nightly/SUMMARY.md', 'utf8');

const issues = await github.rest.issues.listForRepo({
const date = new Date().toISOString().split('T')[0];
const title = `⚠️ Nightly Security Audit Failed — ${date}`;
const body = [
`## Nightly Security Audit — ${date}`,
'',
`- **Brakeman high**: ${{ steps.parse.outputs.brakeman_high }}`,
`- **CVEs found**: ${{ steps.parse.outputs.vulnerabilities }}`,
`- **ZAP high risk**: ${{ steps.parse.outputs.zap_high }}`,
`- **ZAP medium risk**: ${{ steps.parse.outputs.zap_medium }}`,
'',
`[View run artifacts](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})`,
].join('\n');

const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'security,automated'
labels: 'security,automated',
});

const existingIssue = issues.data.find(issue =>
issue.title.includes('Nightly Security Audit Failed')
);

if (existingIssue) {
const existing = issues.find(i => i.title.includes('Nightly Security Audit Failed'));
if (existing) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: `## Update: ${new Date().toISOString()}\n\n${summary}`
issue_number: existing.number,
body: `## Update${new Date().toISOString()}\n\n${body}`,
});
} else {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `⚠️ Nightly Security Audit Failed - ${new Date().toISOString().split('T')[0]}`,
body: summary,
labels: ['security', 'automated', 'critical']
title,
body,
labels: ['security', 'automated', 'critical'],
});
}

- name: Fail on Critical Issues
if: steps.parse.outputs.brakeman_high > 0 || steps.parse.outputs.vulnerabilities == 'true' || steps.parse.outputs.zap_high > 0
if: >
steps.parse.outputs.brakeman_high > 0 ||
steps.parse.outputs.vulnerabilities == 'true' ||
steps.parse.outputs.zap_high > 0
run: |
echo "::error::Critical security issues detected!"
echo "::error::Critical security issues detected — check the uploaded reports."
exit 1
Loading
Loading