Web GUI

Aveloxis includes a web-based GUI for managing repository groups with OAuth login. Users authenticate via GitHub or GitLab, create named groups, and add individual repositories or entire organizations/groups for collection.

Prerequisites

Before starting the web GUI you need:

  1. A working Aveloxis installation with aveloxis migrate already run.

  2. At least one OAuth app registered with GitHub and/or GitLab.

  3. The web section filled in within your aveloxis.json config file.

Creating a GitHub OAuth App

  1. Go to https://github.com/settings/developers.

  2. Click New OAuth App.

  3. Fill in the fields:

    • Application name: anything you like (e.g., “Aveloxis”).

    • Homepage URL: your Aveloxis web GUI URL (e.g., http://localhost:8082).

    • Authorization callback URL: http://localhost:8082/auth/github/callback (replace http://localhost:8082 with your web.base_url if different).

  4. Click Register application.

  5. Copy the Client ID and generate a new Client Secret. Put both in your aveloxis.json under web.github_client_id and web.github_client_secret.

Creating a GitLab OAuth App

  1. Go to https://gitlab.com/-/profile/applications (or the equivalent URL on your self-hosted GitLab instance).

  2. Fill in the fields:

    • Name: anything you like (e.g., “Aveloxis”).

    • Redirect URI: http://localhost:8082/auth/gitlab/callback (replace http://localhost:8082 with your web.base_url if different).

    • Scopes: check read_user.

  3. Click Save application.

  4. Copy the Application ID and Secret. Put both in your aveloxis.json under web.gitlab_client_id and web.gitlab_client_secret.

  5. If using a self-hosted GitLab instance, set web.gitlab_base_url to your instance URL (e.g., https://gitlab.example.com). The default is https://gitlab.com.

Configuration

Important

Local development: Set "dev_mode": true in the "web" section below if you are running over plain HTTP (e.g., http://localhost:8082). Without this, session cookies are marked Secure and your browser will not send them over HTTP, causing login to fail silently.

All web GUI settings live under the web key in aveloxis.json:

{
  "web": {
    "addr": ":8082",
    "base_url": "http://localhost:8082",
    "session_secret": "change-me-to-a-random-string",
    "dev_mode": false,
    "github_client_id": "Iv1.abc123...",
    "github_client_secret": "deadbeef...",
    "gitlab_client_id": "your-gitlab-app-id",
    "gitlab_client_secret": "your-gitlab-app-secret",
    "gitlab_base_url": "https://gitlab.com"
  }
}

Field

Description

Default

web.addr

Listen address for the web server

":8082"

web.base_url

External URL used to construct OAuth callback URLs

"http://localhost:8082"

web.session_secret

Reserved: accepted by the loader and not read elsewhere today (sessions are random tokens held in the process). Set a long random string so an upgrade that starts using it needs no change.

""

web.dev_mode

Set true for local HTTP development. Disables the Secure flag on cookies so they work without HTTPS, and lets a loopback request build email confirmation links when mail.site_url is unset. Do not enable in production — set mail.site_url instead. HttpOnly is always set regardless.

false

web.github_client_id

Client ID from your GitHub OAuth app

""

web.github_client_secret

Client secret from your GitHub OAuth app

""

web.gitlab_client_id

Application ID from your GitLab OAuth app

""

web.gitlab_client_secret

Secret from your GitLab OAuth app

""

web.gitlab_base_url

Base URL for the GitLab instance (for self-hosted)

"https://gitlab.com"

You only need to configure the providers you want to use. If you only use GitHub, you can leave the GitLab fields empty (and vice versa). The login page will only show buttons for configured providers.

Starting the Web GUI

aveloxis web

The server starts on the address specified by web.addr (default :8082). Open http://localhost:8082 in your browser.

Login Flow

  1. On the home page, click Login with GitHub or Login with GitLab.

  2. You are redirected to the provider’s authorization page. Approve access for the Aveloxis OAuth app.

  3. The provider redirects back to Aveloxis with an authorization code.

  4. Aveloxis exchanges the code for an access token and fetches your profile (login, email, avatar).

  5. A session cookie is set in your browser. You are now logged in and redirected to the dashboard.

Your Aveloxis account is tied to the provider’s numeric user ID, not to your user name (v0.29.69). Renaming yourself on GitHub or GitLab keeps your account. A user name is not proof of identity, because anyone can register a name another forge’s user holds, or one a renamed account gave up. So a sign-in whose name already belongs to a different GitHub or GitLab account is refused with “Failed to create user”, and the server log names the collision. Signing in with GitHub and with GitLab under the same name therefore does not link the two accounts. When a user renames on the forge, the account’s name follows unless another account holds the new name.

An administrator resolves a refusal by freeing the name the other account holds. The refused person can then sign in. This works when the holding account carries its forge user ID (gh_user_id or gl_user_id set), because its owner is then found by that ID. An account without one, from before sign-in recorded IDs or loaded from Augur, would be locked out once its name moves. Record its owner’s ID first, for example UPDATE aveloxis_ops.users SET gh_user_id = <the owner's GitHub user ID> WHERE user_id = <N>. The ID is the id field of https://api.github.com/users/<name>. For a GitLab owner, record the instance with the ID, because a GitLab ID matches only on its own instance: SET gl_user_id = <ID>, gl_oauth_host = '<web.gitlab_base_url, lowercased, without a trailing slash>'.

-- the account that holds the name (its owner keeps it and can sign in again,
-- which moves the name back if nobody else has taken it)
UPDATE aveloxis_ops.users SET login_name = login_name || '-renamed' WHERE login_name = 'the-name';

Accounts created before v0.29.69 may include a second account per person, left by a rename, and accounts linked across GitHub and GitLab under one name. The deploy checklist’s two audits count both.

Creating Groups

Groups are named collections of repositories. After logging in:

  1. Click New Group on the dashboard.

  2. Enter a group name and optional description.

  3. Click Create. The empty group appears on your dashboard.

Adding Individual Repos to a Group

  1. Open a group from the dashboard.

  2. Click Add Repository.

  3. Paste the repository URL (e.g., https://github.com/chaoss/augur or https://gitlab.com/fdroid/fdroidclient).

  4. Click Add. The repo is added to the group and queued for collection — at once for an admin, or for a repository already tracked; an ordinary user’s not-yet-tracked repository waits for an admin’s approval.

Platform is auto-detected from the URL, the same as aveloxis add-repo.

A URL is stored without a trailing / or .git, and every add path resolves a URL to that spelling (v0.29.68): pasting https://github.com/chaoss/augur.git or https://github.com/chaoss/augur/ for a repository that is already collected links that repository to the group, and for a non-administrator links it instead of pending as a new repository. Re-adding a collected repository by any path (a paste, the portal API, aveloxis add-repo) never changes its collected description, language or archived flag: those are written by collection only.

An organization’s URL is stored in one spelling — https://, no trailing /, lowercase (v0.29.68): GitHub and GitLab paths are case-insensitive, and re-adding github.com/CHAOSS beside github.com/chaoss used to register the organization twice in the same group. Registrations made before v0.29.68 keep their case; the “already registered” check finds them either way.

When a paste from a non-administrator needs approval, the group page says how many repositories are waiting; an organization waiting for approval, one that could not be added, or one added to a group an administrator rejected, is announced the same way.

Adding an Entire GitHub Org or GitLab Group

  1. Open a group from the dashboard.

  2. Click Add Organization.

  3. Paste the org URL (e.g., https://github.com/chaoss or https://gitlab.com/gnome).

  4. Click Add. All current repositories in the org are added to the group and queued.

Behind the scenes, a row is inserted into the user_org_requests table to track the org for ongoing discovery.

Comparing Repositories

Each group detail page (and the main dashboard) includes a Compare Repositories search widget. This uses the REST API (aveloxis api) to search across all repositories in the database — not just those in the current group. Select up to 5 repos, click Compare, and you are taken to the comparison page with your selection pre-populated.

The API must be running (aveloxis api, at web.api_internal_url — 127.0.0.1:8383 by default) for the compare search to work.

Searching and Pagination

Groups that track organizations can accumulate hundreds or thousands of repositories. The group detail page provides search and pagination to make large lists manageable.

Pagination

Repositories are displayed 25 per page. When a group has more than 25 repos, pagination controls appear at the bottom of the table:

  • First / Last links to jump to the beginning or end.

  • Previous / Next links to move one page at a time.

  • A sliding window of 5 page numbers centered on the current page, so the controls stay compact even with hundreds of pages.

  • The current page number is highlighted.

Search and pagination work together: if you search for chaoss and there are 40 matches, you see 25 on page 1 and 15 on page 2. The search query is preserved as you navigate between pages.

How Org Tracking Works

When you add an org, Aveloxis does not just snapshot the current repo list – it continuously monitors the org for new repos:

  • Newly registered orgs are scanned within seconds. The scheduler checks on every poll tick (default 10 s) for orgs that have never been enumerated (last_scanned IS NULL) and scans them immediately. This fires when an admin adds an org directly, when an admin approves a user’s pending org request, and when a user’s add of an org already registered in a group that is not rejected auto-approves — so repositories that are already collected (for example an org tracked by another group) appear in the new group right away, without re-collection. The aveloxis serve process must be running: it owns all forge traffic, so nothing links while it is stopped.

  • A scheduler task additionally runs every 4 hours and re-fetches the repository list for every org in user_org_requests, picking up repos created after the initial scan.

  • Any newly created repos that are not already in the database are added to the group and queued for collection automatically.

  • Repos that are deleted or made private on the forge are handled by the existing dead repo sidelining logic during collection.

This means you can add https://github.com/kubernetes once and Aveloxis will automatically pick up new repos as the Kubernetes org creates them.

How Repos Get Queued for Collection

Repos added through the web GUI (individually or via org tracking) are inserted into the same aveloxis_ops.collection_queue used by the CLI. They are collected by aveloxis serve in priority order, just like repos added via aveloxis add-repo.

You must have aveloxis serve running for collection to happen. The web GUI only manages the queue – it does not collect data itself.

Session Management

  • Sessions are stored in-memory on the web server process.

  • Each session expires 24 hours after login (not refreshed by use).

  • Restarting aveloxis web clears all sessions. Users will need to log in again.

  • The session cookie carries a random token; it is not signed, so web.session_secret plays no part today (the API’s Bearer tokens, minted at /auth/token, are stored in the database and survive restarts).

Running Alongside aveloxis serve

The web GUI and the collection scheduler are separate processes. In a typical deployment you run both:

# Terminal 1: collection scheduler with monitoring dashboard
aveloxis serve --workers 4 --monitor 127.0.0.1:5555

# Terminal 2: web GUI for group management
aveloxis web

# Terminal 3: the REST API the charts and the compare search read
aveloxis api

Or all three in the background with aveloxis start all. They share the same PostgreSQL database. The web GUI writes to the queue; the scheduler reads from it. There is no direct communication between the two processes, except that web proxies /api/* to the API at web.api_internal_url.

You can run them on different hosts as long as both can reach the database.

Security Considerations

  • OAuth tokens: The access tokens obtained during login are used only to fetch the user’s profile and are not stored persistently. They are held in the session for the duration of the login.

  • Session cookies: A random 256-bit token looked up in the process; unguessable rather than signed. All cookies set HttpOnly to prevent JavaScript access. The Secure flag is set in production (default) but can be disabled for local HTTP development via "dev_mode": true.

  • HTTPS: In production, run aveloxis web behind a reverse proxy (nginx, Caddy, etc.) that terminates TLS. OAuth providers require HTTPS callback URLs for production apps (localhost is exempt during development). Leave dev_mode at its default (false) in production — this ensures cookies are only sent over HTTPS.

  • Development mode: For local development over plain HTTP, set "dev_mode": true in the web section of aveloxis.json. This disables the Secure cookie flag so session cookies work without HTTPS, and lets a loopback request build email confirmation links when mail.site_url is unset. HttpOnly remains enabled even in dev mode. Never deploy with dev_mode enabled; production confirmation links need mail.site_url.

  • Client secrets: The web.github_client_secret and web.gitlab_client_secret values in aveloxis.json are sensitive. Protect the config file with appropriate file permissions (chmod 600 aveloxis.json).

  • Roles: the first account to sign in is the admin; every later account is an ordinary user until an admin promotes it on the users page. Ordinary users create groups freely, but a repository or organization they add that is not yet tracked waits for an admin’s approval before it is collected (web.auto_approve_add_limit auto-approves small repository batches, never organizations). To restrict who can sign in at all, control reach at the network level.