genroc

    docs / Guides / Operating

    Genroc UI

    Learn about genroc user interface.

    Genroc UI offers a simple way to see the state of your processes.

    Current state

    Genroc UI is experimental at this stage and offers minimal functionality.

    How to install

    Genroc UI is distributed as a separate docker container. The easiest way to start is to create a new project with the UI option:

    genctl init --ui

    The UI is configured inside the compose.yaml.

    The setup

    Your compose.yaml file will now have the following entry:

      genroc-ui:
        image: ghcr.io/genroc/ui:edge
        command: [--server, "http://genroc:8448"]
        ports: ["8448:8448"]
        restart: unless-stopped
        depends_on: [genroc]

    The UI takes port 8448, which is where genctl looks by default, and passes API requests on to genroc. That's why genroc itself isn't exposed.

    With authentication enabled

    When authentication is enabled, the UI signs users in before letting them access the genroc server. Create the project with both options:

    genctl init --ui --auth

    In this setup the init command also adds a ui.yaml file, which is mounted into the genroc-ui container. It will look something like this:

    server: http://genroc:8448
    
    login:
      passwords:
        - email: admin@localhost
          hash: "$2a$10$DgtdyEbHuKTY/eKkNU9nJOB7Rz.j3ntkWvMncSwGhGcmaXZrTagDm"
          groups: [admins]
    
    token:
      secret_file: /data/jwt-secret
    
    roles:
      admins: [admin]

    And the compose.yaml:

      genroc-ui:
        image: ghcr.io/genroc/ui:edge
        environment:
          GENROC_UI_CONFIG: /etc/genroc/ui.yaml
        ports: ["8448:8448"]
        volumes:
          - ./ui.yaml:/etc/genroc/ui.yaml:ro
          - ./data/jwt-secret:/data/jwt-secret:ro
        restart: unless-stopped
        depends_on: [genroc]

    The jwt-secret file is a secret shared by both containers. For every request, Genroc UI signs a short-lived token with it, and genroc checks the signature with the same file (genroc reads it through GENROC_JWT_SECRET_FILE). Both have to point at the same file.

    By default Genroc UI signs users in with a static list of users from ui.yaml. Passwords are generated and never kept in plain text, only their hash is stored. You can add a new user with the following command:

    > genctl init password user@localhost
    password  fvpzqXzcPdquYW66
    
    Put this under `login.passwords` in ui.yaml, replacing the entry for user@localhost if it is
    already there, then `docker compose restart genroc-ui` — sessions survive it:
    
        - email: user@localhost
          hash: "$2a$10$ZoNrzhck4aIUvrtt.8d1BuQFStXbIQkwJ.5wkEwr2WMTGwFoeNaFm"
          groups: [admins]

    This generates a random password for the user and the entry for ui.yaml, including the hash. This way you can also replace a password that was forgotten.

    User groups and roles

    ui.yaml is also the place where you configure user permissions. Each user belongs to some groups, and the groups have permissions (the roles section). The permissions are the same as for tokens, see Permissions.

    Using auth provider

    Genroc UI doesn't have any user management system, but it allows you to connect to an external provider through OIDC (OpenID Connect).

    Add the provider under login.providers in ui.yaml. Any OIDC provider works, for example Okta, Entra, Auth0 or Keycloak:

    login:
      providers:
        - id: okta
          name: Okta
          issuer: https://example.okta.com
          client_id: ...
          client_secret: ...

    Register http://localhost:8448/auth/callback as the redirect URL of the client in your provider. Each provider becomes one button on the sign-in page. With a single provider and no passwords, the sign-in page is skipped and users go straight to the provider.

    Groups are read from the groups claim of the provider's token and matched against roles. Some providers don't send groups at all, Google for example. Then you can give permissions to each user by email in the users section:

    login:
      providers:
        - id: google
          name: Google
          issuer: https://accounts.google.com
          client_id: ...
          client_secret: ...
          scopes: [openid, email, profile] # Google refuses the default `groups` scope
    
    users:
      ada@example.com: [admin]

    Dex

    Providers that don't support OIDC (GitHub, LDAP, SAML) need a broker in between. Dex is a good fit: it signs the user in with the provider and gives Genroc UI a regular OIDC token, groups included. Dex can also read Google Workspace groups, which Google itself doesn't put into the token.

    See the Dex example for a complete setup with docker compose. It runs with Dex's own users, so you can try it without any credentials, and shows how to switch to GitHub.

    All ui.yaml options are listed in the Genroc UI reference.