Loading page...Загружаем страницу...正在加载页面...
AtlasRepo

We Built a Hackathon Platform Where Every Rule Lives at the Layer That Can't Be Bypassed

Description and use

The platform enforces all critical rules at the layer that owns them, making bypass architecturally impossible. This design improved security, fairness, and reliability while exposing the cost of microservices in resource usage.

Problem

Ensuring that critical rules (role isolation, deadline enforcement, score fairness, commit integrity, webhook trust, concurrency safety) cannot be bypassed by clients or developers in a hackathon platform.

Outcome

The platform enforces all critical rules at the layer that owns them, making bypass architecturally impossible. This design improved security, fairness, and reliability while exposing the cost of microservices in resource usage.

Workflow

  • 1. Capture JWT claims in gateway and inject X-User-Id into request headers.
  • 2. In application layer, filter score queries by judge_id from verified JWT claim, not request parameters.
  • 3. Set PostgreSQL session variable app.current_user_id from JWT claim before each query and enforce RLS policy judge_own_scores.
  • 4. Enforce submission deadline using Redis SETNX lock and server‑side timestamp comparison.
  • 5. Normalize scores with z‑score per judge and apply Bayesian shrinkage (k0=5) to dampen low‑review judges.
  • 6. Scan submitted repo URLs with in‑memory Eclipse JGit to compute risk score based on commit history.
  • 7. Publish score.submitted events to RabbitMQ for asynchronous normalization, audit logging, webhook dispatch, and notifications.
  • 8. Use Redis token‑bucket for voting rate limiting and Redis SETNX for deadline lock.
  • 9. Deploy services as separate Spring Boot microservices with isolated Flyway‑managed schemas.
  • 10. Monitor resource usage and migrate to cloud shell when local Docker Compose exceeds limits.

Evidence

Layer 1 — Application: every score query filters by judge_id taken from the verified JWT claim (X-User-Id injected by the gateway), never from a request parameter.

Source

Layer 2 — Database engine: PostgreSQL Row-Level Security keyed on a session variable set from that same claim before every query: SET LOCAL app.current_user_id = '<uuid-from-jwt>'; CREATE POLICY judge_own_scores ON judging.scores USING ( judge_id = current_setting('app.current_user_id')::uuid OR current_setting('app.current_role', true) IN ('ORGANIZER','ADMIN') );

Source

The Submission Service enforces the cutoff on the server with a Redis distributed lock (SETNX) and compares against the event's stored deadline using server time.

Source

We apply Bayesian shrinkage with k0 = 5 to handle judges with few reviews: λ = k / (k + 5) ; z_shrunk = λ × z + (1 − λ) × global_mean.

Source

The Submission Service runs an in-memory Eclipse JGit scan on every submitted repository URL and records a risk score: 0 commits → risk 100 (EMPTY_REPOSITORY) 1 commit → risk 80 (SINGLE_COMMIT_DUMP) >90% commits before event start → HIGH (PRE_HACKATHON_CODE).

Source

  • Record date: 2026-10-04T14:56:04.606Z