Members and teams
Roles
Every org member has exactly one org-level role.
| Role | What they can do |
|---|---|
| Owner | Full org admin: manage billing, configure SSO and SCIM, manage security policy, invite and remove members, create and delete repositories, access all repository settings, view audit log |
| Member | Access repositories they have been granted access to; create new repositories (if the org policy permits); no access to org admin settings |
| Reader | Read-only access to repositories they have been granted access to — clone, browse, read issues and pull requests. Cannot push, create repositories, or reach org admin settings. Readers do not consume a billable seat — see Free readers below |
| Guest | Read-only, but scoped to specific repositories rather than the whole org. Same abilities as a Reader on the repos they are given. Free — Guests do not consume a billable seat |
| Collaborator | Write access scoped to specific repositories. Can push, and open and close issues and pull requests, on those repos only. No org admin access. Consumes a billable seat |
| Auditor | Read-only access to everything: every repository, and the org admin settings an Owner sees, without being able to change anything. The first 5 auditors in an org are free; a sixth or later auditor consumes a billable seat — see Auditors below |
An org must have at least one Owner at all times. You cannot remove or demote the last Owner.
How a seat is decided
One rule covers every role above:
You occupy a billable seat if you can write somewhere. If everything you hold is read-only — or you hold nothing — you are free. The one exception is the Auditors team: its first 5 read-only members are free, and each one after that is a billable seat.
Apart from Auditors, that is decided by the permission your teams grant, not by their names. So a read-only team you create yourself is free at any scope, and renaming a team never changes what you pay. Owners, Members and Collaborators can write, so they are billable; Readers and Guests cannot, so they are not.
Inviting members
Member management lives in the fremforge admin UI at /<org>/_admin/members — the Members page lists every current member with per-member Manage drawers and an Invite dialog at the top. Forgejo’s native frem.sh/org/<org>/teams page remains available as a fallback when you need to compose finer-grained team permissions; the in-product page covers the day-to-day invite / role / remove flow.
- Go to Org admin → Members (
/<org>/_admin/members). - Click Invite member.
- Enter the invitee’s username or email address and pick a role.
- Click Send invitation.
The invitee receives an email from noreply@frem.sh with an accept link. The link is valid for 72 hours (Forgejo-managed). If it expires, re-send it from the Pending invitations section on the same page.
In the Pending invitations section, the invitee appears as Pending until they accept. Pending members:
- Cannot access any org resource.
- Do not count as a billable seat until they accept the invitation.
- Can be cancelled at any time by removing them from the team while still pending.
Once the invitee accepts, their status changes to Active and they are added to the billable seat count at the next billing cycle. Activity is not required, acceptance is what counts.
Free readers (read-only, no billable seat)
A Reader has read-only access to the repositories they’re granted — clone, browse code, read issues and pull requests — but cannot push, create repositories, or reach org admin settings. Readers are free: they do not count against your seat cap and are never billed. Add as many as you like — stakeholders, contractors who only need to look, read-only dashboards, and so on. Someone who also needs to read your org settings, such as a compliance auditor, belongs in Auditors instead.
Under the hood a Reader is a member of the org’s canonical Viewers team and of no team that grants write. Seat counting follows the permission a team grants, not its name: hold nothing but read-only teams and you are free; hold write anywhere and you are billed. (If you add someone to Viewers and Members, they are billed — write wins.)
Because the rule is permission-based rather than name-based, a read-only team you create yourself — Stakeholders, Reviewers, whatever you call it — is also free, and scoping it to a handful of repositories does not change that. Use Guests when you want exactly that: free read, on chosen repositories. The canonical Auditors team is not one of these: fremforge creates it, it reaches org settings as well as code, and only its first 5 members are free (see Auditors).
Add a reader
Any of these work; the in-product path is the simplest:
- From the Members page (recommended). Go to Org admin → Members (
/<org>/_admin/members) → Invite member → enter the email → in Team(s), select Viewers (and nothing else) → Send invitation. When they accept, they join as a free reader. - Convert an existing member. Open the member’s Manage drawer and move them to Viewers (remove them from Members/Owners). They drop out of the billable seat count at the next billing cycle.
- Automatically via SSO. Map an identity-provider group to the Viewers team (see SSO and SCIM). Everyone in that group is provisioned as a free reader — no per-person invite needed.
- Forgejo-native fallback.
frem.sh/org/<org>/teams→ Viewers → Add team member. Use this only when you need finer team composition; the Members page covers the normal case.
Free readers are counted separately from paid seats in your billing summary (Org admin → Billing) and in the seats API, so you can always see how many free readers you have versus how many billable seats you’re using.
Not the same as a docs-only reader. If you want someone who can read your published docs but has no repository access and no Forgejo account at all, don’t add them to Viewers — instead give their SSO group an empty group→team mapping. See Wiki and public docs. A Reader (Viewers team) does get a Forgejo account and read access to granted repos; a docs-only reader does not.
Guests (free read, specific repositories)
A Reader can read every repository in the org. A Guest reads only the repositories you choose. Both are free — reading code never costs a seat, whatever its scope.
Use Guests for a contractor reviewing one service, an auditor who needs two repositories rather than forty, or a partner team you want to keep out of everything else. It is the least-privilege version of a Reader, and it costs the same: nothing.
Guests are the canonical Guests team, which is created in every org and is scoped to specific repositories rather than all of them.
Add a guest
- Go to Org admin → Members → Invite member → enter the email → in Team(s), select Guests (and nothing else).
- Choose which repositories the Guests team can read:
frem.sh/org/<org>/teams/guests→ Repositories → add the repositories you want. - Send the invitation. When they accept they can read exactly those repositories.
To move an existing free Reader down to specific repositories, open their Manage drawer and move them from Viewers to Guests. They stay free either way.
Guests and Collaborators are managed by fremforge and cannot be deleted. They set what you pay — Guests keeps repository-scoped readers free, Collaborators is what makes a repository-scoped writer a paid seat. Removing either would silently re-price your org, so both are locked, like Members and Viewers. You can freely change which repositories each one covers, and who is in it.
Auditors
An Auditor can look at everything in your org and change nothing. Use it for a compliance or security auditor, an internal control function, or anyone who has to review how the org is configured rather than just read its code.
Every org has a canonical Auditors team, created and managed by fremforge. It has read access to all repositories, and its members can also open the org admin settings. Like the other canonical teams it is locked: you cannot delete it, rename it or give it more than read access. An owner decides who is in it.
What an auditor can see
- Every repository, read-only, like a Reader: clone, browse code, read issues and pull requests.
- The org admin settings at
/<org>/_admin/and the matching reads on the REST API: policies, security settings, SSO, members, billing and the audit log. This includes what an Owner sees about people: on the Members page, members’ email addresses, full names, last login and MFA status, and on the billing settings, the billing contact and payment mandate IDs. - Org and repository settings in Forgejo (
frem.sh/org/<org>/settings, a repository’s Settings), read-only. - Compliance evidence and attestations. An auditor can fetch them; every fetch is recorded in the audit log.
A banner on every admin page says you are viewing as a read-only auditor. Buttons and forms that would change something are disabled.
What an auditor cannot do
- Change anything. Every request other than a read is refused, in the admin pages, on the API and in Forgejo, before it reaches the endpoint. On the fremforge API the refusal is a
403with theauditor-read-onlyerror. An auditor cannot add or remove members, including other auditors. - Take data out in bulk or see credentials. These are refused even as a read: the data export, SBOM downloads, the billing export and invoice PDFs, raw CI logs, the webhook pages and webhook API, the Forgejo Actions runner pages and the runner registration-token API, and the org-delete page.
If an auditor needs one of those files or a change, they ask an owner. An API token an auditor uses only ever carries read access.
Add an auditor
- New person. Go to Org admin → Members (
/<org>/_admin/members) → Invite member → enter the email → in Team(s), select Auditors → Send invitation. - Existing member.
frem.sh/org/<org>/teams→ Auditors → Add team member.
To remove an auditor, remove them from the Auditors team. Their access to the admin settings ends within 5 minutes.
Someone in Auditors and in Owners is an Owner. Someone in Auditors and in a team that can write (such as Members) keeps their write access to code and is a read-only auditor on the settings.
Seats
- The first 5 auditors in an org are free.
- A sixth or later auditor is a billable seat, counted against your seat cap like any other. When seats are full, the usual seats-full rules apply.
- An auditor who is also in a team that can write already holds a seat for that, so they cost nothing extra and do not use one of the 5 free places.
- The free places are not reserved for particular people: when one of the first five leaves, the next auditor takes the free place.
Every auditor read is logged
Owners’ reads of the admin settings are not logged; auditors’ are. Each page or API endpoint an auditor reads is recorded in the audit log as a tenant.auditor.read event, at most once per auditor and endpoint every 10 minutes. Refused attempts are logged every time.
A team you already called “Auditors”
If your org already had a team of your own named Auditors before fremforge introduced the role, fremforge left it alone. It stays an ordinary team: its members do not get access to the admin settings, and it is priced like any other team you made.
When seats are full
If your org has reached its seat cap, a member who tries to access the org is shown a “seats full” page at /<org>/seats-full instead of the resource they requested. From that page they can send a one-click request to the org’s owners to add a seat.
Owners receive that request (by email and in the admin notifications bell) and can add a seat from Org admin → Billing, which clears the block for the waiting member. Raise the seat cap before the member can proceed; until then their access stays paused at the seats-full page.
The cap also applies to members your identity provider adds through SSO group sync: at sign-in, group sync does not put anyone on a team with write access once the org’s paid seats are used up (read-only teams are free and always allowed). A change to the cap or to seat overage on the Billing page applies to group sync as soon as you save it. So does saving an SSO source or its group-to-team mapping, which makes sure the current cap is in place before that source’s next sign-in.
Changing roles
A member’s role (Owner, Member, or Reader) is changed in-product from the Manage drawer on the Members page. Under the hood the role maps to Forgejo team membership: Owners = full org admin, Members = scoped read/write access defined by the team’s repo grants, Viewers = read-only (and free). Moving a member into Viewers-only drops them from the billable seat count at the next billing cycle.
- Go to Org admin → Members (
/<org>/_admin/members). - Open the Manage drawer for the member.
- Pick the new role and confirm. The matching Forgejo team change is applied immediately.
For finer team composition (custom teams, repo-scoped grants) use the Forgejo-native team page at frem.sh/org/<org>/teams. Role changes take effect immediately. There is no grace period or confirmation email sent to the member.
Removing a member
- Go to Org admin → Members (
/<org>/_admin/members). - Open the Manage drawer for the member and choose Remove member.
- Confirm the removal.
What happens immediately:
- Access to all org repositories is revoked.
- Any active sessions (browser or API) for that user are invalidated.
- The member is removed from any team assignments within the org.
What does not change:
- Repositories are not deleted. Repos belong to the org, not to individual members. A member who owned repos in the org does not take those repos when they leave.
- Issues, PRs, and commits remain attributed to their username. Historical contribution records are preserved.
- Open PRs and issues they authored remain open and unmodified.
The removed member is taken out of the billable seat count at the next billing cycle. There is no credit for the current period.
Offboarding checklist
When a member leaves the org, run through this checklist before completing the removal.
- Transfer repository ownership if the departing member owns any repos directly (check Org admin → Repositories for repos with their username as owner). Transfer to the org or to another member before removing them.
- Rotate secrets they may have known. Check which secrets were created or last updated while they had access. Rotate any that are now exposed by their departure.
- Revoke API tokens they created. Go to Org admin → API tokens (
/<org>/_admin/api-tokens) to see all org API tokens. Revoke any token created by the departing member. - Check for personal access tokens (PATs). PATs are tied to the user’s account, not the org. Once removed from the org, their PATs can no longer access org resources. But if the departing member was an Owner, confirm no tokens with elevated scopes were shared with external systems under their name.
- Review active integrations and webhooks. If any webhook or external integration is authenticating as this user, update it to use an org API token or another account.
SCIM-managed deprovisioning
If SCIM provisioning is configured for the org, user lifecycle is managed by the connected IdP (Okta, Entra ID, etc.). Deactivating or removing a user in the IdP deactivates them in fremforge automatically within the SCIM sync interval, which is typically under five minutes.
When a user is deactivated via SCIM:
- Their fremforge session is invalidated immediately.
- They cannot sign in via SSO or local password.
- Their seat is removed from the billable count at the next billing cycle.
Manual removal via Org admin → Members is not required when SCIM is active. The IdP is the source of truth for membership. Removing a user in fremforge without deactivating them in the IdP will cause SCIM to re-provision them on the next sync.
See SCIM provisioning for setup instructions.
SSO-only members
A member who has only ever signed in via SSO has no local fremforge password. Their identity is entirely controlled by the IdP.
To block a SSO-only member’s access:
- Revoke their access in the IdP (deactivate the account, remove from the app assignment, or disable SSO for their account).
- Optionally remove them from the org in fremforge to clean up the seat count.
Revoking IdP access alone is sufficient to prevent sign-in. The fremforge session will fail at the next SSO validation check. If SCIM is enabled, the IdP deactivation also triggers automatic deprovisioning without the manual org removal step.
Re-inviting a former member
To re-invite someone who was previously removed, send them a fresh invitation from Org admin → Members → Invite member as normal.
When they rejoin:
- Previous commits, issues, and PRs remain attributed to their username.
- Repository access is determined freshly by org role and any repo-level collaborator assignments. No previous access configuration is automatically restored.
If the former member deleted their fremforge account after leaving, their username may show as a deleted-account indicator on historical contributions. If a different person has taken that username in the interim, historical attribution reflects the original account via the underlying user ID, not just the username string.
Per-repository permissions
Org-level roles determine baseline access. For finer-grained control, you can add individual users as collaborators on specific repositories.
Add a collaborator:
- Go to Repository → Settings → Collaborators.
- Search for the user by username or email.
- Select a permission level:
| Permission | What they can do |
|---|---|
| Read | Clone, pull, view issues and PRs |
| Write | Read access plus push branches, create and close issues and PRs |
| Admin | Write access plus manage repository settings, branch protection, webhooks, and secrets |
Collaborator permissions are additive on top of the user’s org role, not a replacement — the higher of the two applies. A Reader with Write collaborator access on a repo can push to that repo. An Owner collaborator gains nothing beyond what the Owner role already grants.
Collaborators must be members of your org
A collaborator has to be a member of the organisation that owns the repository. You cannot attach someone from another organisation, and you cannot add an outside account directly to a repository — invite them to the org first (as a Guest if they only need read), then grant repository access.
This is a change from earlier behaviour, where a repository admin could attach any existing account on the instance. Requiring membership means everyone with access to your code appears in Org admin → Members, which is also what makes access reviews and offboarding complete.
What a collaborator costs
Only write costs a seat:
| Collaborator permission | Seat |
|---|---|
| Read | Free — same as a Guest, scoped to that repository |
| Write or Admin | Consumes a billable seat |
Granting write to someone who is currently free (a Reader or Guest) automatically adds them to the canonical Collaborators team, which is what makes them a paid seat. You do not have to move them by hand. Someone who is already billable — a Member, an Owner, or an existing Collaborator — is not charged twice.
If that seat would take you past your seat cap:
- With seat overage enabled, the grant succeeds and the extra seat appears on your next invoice.
- With seat overage disabled, the grant is refused and you are pointed at Org admin → Billing → Seats. Turning seat overage off at Org admin → Billing is how you stop fremforge adding paid seats automatically — the same switch that governs invitations and SSO-provisioned members.
Removing someone’s seat does not remove their access outright. Write grants that are no longer covered by a seat are reduced to read after a 7-day grace period, so losing a seat turns a Collaborator into the equivalent of a Guest rather than locking them out. Restore the seat within that window and nothing changes.
Via REST API
The day-to-day member-lifecycle flow (invite / list / revoke / remove) is available on the public API surface. Use this when scripting onboarding from an HRIS, automating offboarding, or driving operations from an AI agent.
- List invitations
GET /_app/api/v1/orgs/:slug/members/invitations?status=pending(scopeseats:read) - Invite a member
POST /_app/api/v1/orgs/:slug/members/invitationsbody:{ "email": "...", "full_name": "...", "team_names": [...] }(scopeseats:write) - Revoke a pending invitation
DELETE /_app/api/v1/orgs/:slug/members/invitations/:id(scopeseats:write) - Remove a member
DELETE /_app/api/v1/orgs/:slug/members/:login(scopeseats:write) - Grant / dismiss a seat hold
POST /_app/api/v1/orgs/:slug/members/seat-holds/:id/grantor.../dismiss(scopeseats:write)
Requires a Personal Access Token (PAT) with the seats:write scope:
curl -X POST \
-H "Authorization: Bearer ${FREMFORGE_PAT}" \
-H "Content-Type: application/json" \
-d '{"email":"new.hire@example.com","full_name":"New Hire","team_names":["engineering"]}' \
https://frem.sh/_app/api/v1/orgs/acme/members/invitationsSee the public REST API reference for the full OpenAPI specification.
Cross-references
- SCIM provisioning, automated user lifecycle via Okta, Entra ID, or any SCIM 2.0-compliant IdP
- OIDC SSO, configure SSO so members sign in with their corporate identity
- Billing, how seats are counted and when removed members leave the billable count
- Org admin, full reference for the org admin surface
- API, manage members programmatically via the REST API