Skip to content

Add per-leaderboard allowed_users gating for private hackathons#454

Closed
msaroufim wants to merge 3 commits into
mainfrom
hackathon-role-gating
Closed

Add per-leaderboard allowed_users gating for private hackathons#454
msaroufim wants to merge 3 commits into
mainfrom
hackathon-role-gating

Conversation

@msaroufim

@msaroufim msaroufim commented Mar 4, 2026

Copy link
Copy Markdown
Member

No description provided.

Adds an `allowed_users TEXT[]` column to leaderboards so submissions can
be restricted to an allowlist of GitHub usernames. When NULL (default),
the leaderboard remains open. When populated, only listed users can submit
via the API (popcorn-cli). Discord bot submissions are gated by checking
for a role matching the leaderboard name prefix (e.g. "helion").

- Migration: add allowed_users column
- DB: get_leaderboard returns allowed_users, add set_allowed_users method
- API: 403 in to_submit_info when user not in allowlist
- Admin endpoints: GET/PUT /admin/leaderboards/{name}/allowed-users
- Discord: role check in submit() for allowlisted leaderboards
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  src/libkernelbot
  db_types.py
  leaderboard_db.py 629, 653, 679
  utils.py
Project Total  

This report was generated by python-coverage-comment-action

Step-by-step runbook for day-of hackathon setup: collecting GitHub
usernames, setting the allowlist via admin API, adding/removing
participants mid-event, and opening leaderboards back up afterward.
@msaroufim msaroufim requested review from S1ro1 and ngc92 March 4, 2026 01:14
Comment thread src/kernelbot/api/main.py
_: Annotated[None, Depends(require_admin)],
db_context=Depends(get_db),
) -> dict:
if "usernames" not in payload:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slop; that's the helper above

gpu_types=self.get_leaderboard_gpu_types(res[1]),
description=res[7],
)
if res[8] is not None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make an explicit get function and fetch this only on-demand?

steps = [
step(
"""
ALTER TABLE leaderboard.leaderboard

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats the design trade-off here on having a column vs having an extra table?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Column approach (TEXT[]) is simpler for this use case: the allowlist is always read/written as a whole unit, the list is small (tens of users max), and it avoids the extra join on every submission check. A separate table would make sense if we needed per-user metadata (e.g., added_by, added_at), needed to query across leaderboards ("which leaderboards is alice on?"), or if the lists grew large. For now the column keeps things simple.

raise LeaderboardDoesNotExist(leaderboard_name)
self.connection.commit()

def append_allowed_users(self, leaderboard_name: str, usernames: List[str]) -> List[str]:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fancy SQL vs just processing this on the python side?

@msaroufim msaroufim closed this Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants