title: Organizations description: Create organizations, add people by username or email, manage roles and invitations, set the organization's picture, and share repositories and secrets.
An organization is a shared account that owns repositories, agents, container images and Actions secrets on behalf of a group of people. Use one when more than one person works on the same code, so access doesn't depend on any one personal account.
Organization roles
Every member has one of three roles. The role decides what they can do in the organization and the role they get on every repository the organization owns.
| Capability | member | admin | owner |
|---|---|---|---|
| Role on every organization repository | write | admin | admin |
| See the organization's private repositories | Yes | Yes | Yes |
| Create repositories in the organization | Yes | Yes | Yes |
| Create container images in the organization and pull its images | Yes | Yes | Yes |
| Push to, delete and change the settings of an organization image that isn't linked to a repository | Only images they created | Yes | Yes |
| See the People and Agents tabs | Yes | Yes | Yes |
| Add people (by username or email) | No | Yes (as member or admin) | Yes (any role) |
| See and revoke pending invitations | No | Yes | Yes |
| Change roles, remove members | No | Yes, except owners | Yes, including owners |
| Create and manage the organization's agents | No | Yes | Yes |
| Manage organization Actions secrets | No | Yes | Yes |
| Change the organization's picture through the API | No | Yes | Yes |
| Open the Settings tab: rename, display name, picture | No | No | Yes |
| Get emails when repositories are created or deleted in the organization | No | Yes | Yes |
Site administrators can do everything an owner can in every organization, and have admin on every repository.
A container image linked to a repository follows that repository's roles instead (read pulls, write pushes, admin deletes). See Container registry.
A member's role on a repository is the highest of their organization role's repository role and any role given to them directly on that repository. A direct collaborator role can raise an organization member's access (for example to maintain or admin) but never lowers it. See Permissions for what each repository role allows.
Create an organization
Any active account can create an organization and becomes its first owner.
In the web UI
- Go to Settings → Organizations (
/settings/orgs), or click New organization on your dashboard. - Under New organization, enter the Organization name (for example
acme) and optionally a Display name (for exampleAcme Inc.). - Click Create organization.
Diffinery opens the new organization's People tab, where you can add people right away.
With the API
curl -X POST https://diffinery.com/api/v3/user/orgs \
-H "Authorization: Bearer dfy_..." \
-H "Content-Type: application/json" \
-d '{"login": "acme", "name": "Acme Inc."}'
The response (201 Created) describes the organization, with "type": "Organization" and its html_url.
Creating an organization through the API needs a personal access token with the admin scope that isn't restricted to repositories. A read or write token gets 403 this token needs the admin scope, and a restricted token gets 403 this token is limited to repositories and can't change account settings. In the browser no token is needed.
Name rules
The organization name is its URL (https://diffinery.com/acme) and the owner part of every repository URL. It shares one namespace with usernames and agent names.
- Starts with a letter or digit, then letters, digits,
-and_, up to 100 characters. Dots aren't allowed. - Not already used by a person, organization or agent: "name already taken".
- Not reserved (for example
api,settings,new,login,admin,docs): "invalid or reserved organization name".
The organization page
Open https://diffinery.com/acme (you need to be signed in). The header shows the organization's picture, display name, name and your role ("you are an owner", "you are an admin" or "you are a member"). The tabs are:
| Tab | Who sees it | What it shows |
|---|---|---|
| Repositories | Everyone signed in | Repositories you can see. Members get a New repository button. |
| People | Everyone signed in | Members and their roles. Owners and admins also get the Add people form and the Pending invitations list. |
| Agents | Everyone signed in | The organization's agents, their maximum role and status. Owners and admins get a Manage agents button. |
| Settings | Owners | The organization's picture, name and display name. Others get 403 organization owners only. |
| Packages | Everyone signed in | Container images the organization owns (/acme/-/packages). See Container registry. |
People who aren't members only see repositories that are public, or that they were added to directly.
Add and remove members
Owners and admins manage members on the People tab. The top of the tab shows how many members and pending invitations there are, for example "4 members · 1 pending invitation".
Add people
The Add people form takes a username or an email address, like GitHub's "Add people" or "Invite member" dialog:
- Open
https://diffinery.com/acme?tab=people. - In Username or email, enter a username (
octocat, or@octocat) or an email address (friend@example.com). - Choose a Role: Member (default) or Admin. Owners can also choose Owner.
- Click Add.
What happens depends on who you entered:
| You entered | Result |
|---|---|
| The username of a person | They become a member right away, with no invitation to accept. You see "Added octocat to acme as member. We let them know." They get an email ("You're now a member of acme", naming who added them) and an in-app notification ("<your username> added you to acme as a member"). |
| The email address of someone who already has an account | The same as entering their username: they are added right away. |
| An email address with no account | Diffinery creates an invitation and emails it. The page shows Invitation sent to friend@example.com with the link and a copy button: "They don't have an account yet, so we emailed them an invitation. You can also send them this link yourself. It works once and expires in 14 days: opening it creates their account and passkey and adds them here." |
A person whose account is waiting for an invite (pending) becomes active when you add them by username or email. See Invitations for how invitations work, including inviting from the CLI and API.
| Message | Cause |
|---|---|
| "enter a username or an email address" | The field was empty. |
| "enter a valid email address" | The text has an @ but isn't a complete address such as friend@example.com. |
| "no one has the username octocat; to invite someone new, enter their email address" | No account has that username. Enter their email address to invite them. |
| "review-bot is not a person; agents belong to an organization through Settings → Agents" | Agents and organizations can't be members. Create an organization agent instead (see Organization agents). |
| "octocat's account is disabled" | A site administrator disabled the account. |
| "octocat is already a member of acme" | Change their role in the members table instead. |
| "friend@example.com already has a pending invitation; revoke it first to send a new one" | Revoke the invitation under Pending invitations, then add the address again. |
| "only owners can add owners" | Admins can add members and admins only. |
| "organization admins only" | Only owners, admins and site administrators can add people. |
Pending invitations
Owners and admins see a Pending invitations list on the People tab with each invitation's email address, who invited them and when, the expiry date and the role. Accepted and expired invitations aren't listed.
To withdraw an invitation, click Revoke and confirm "Revoke the invitation for friend@example.com? The link stops working." You see "Invitation revoked." Opening the revoked link shows "this invite is invalid, already used, or expired". The person isn't told.
Change a member's role
In the member's row, pick a new role (Owner, Admin or Member) in the Role menu and click Save. The member gets an email saying their role changed and who changed it.
Remove a member
Click Remove in the member's row and confirm "Remove octocat from acme?". The member loses the organization's repository access on their next request, including through their tokens, and gets an email saying they were removed. Their personal repositories and accounts are not affected.
Rules:
| Rule | Message |
|---|---|
| Only owners can promote someone to owner, change an owner's role or remove an owner. | "only owners can manage owners" |
| An organization always keeps at least one owner: you can't remove or demote the last one. | "an organization needs at least one owner; make someone else an owner first" |
| Only owners and admins can manage members. | "organization admins only" |
| The username must belong to a person. | "user not found" |
Leave an organization
There is no separate Leave button. Ask an owner or admin to remove you. Owners and admins can remove themselves from the People tab, as long as another owner remains.
Organization repositories
Any member can create a repository owned by the organization.
- Web UI: click New repository on the organization's Repositories tab, or choose the organization as Owner on the Create a new repository page (
/new). - CLI:
diffinery repo create website --org acme(add--publicfor a public repository; the default is private). - API:
POST /api/v3/orgs/acme/reposwith{"name": "website", "visibility": "private"}. The CLI and API need a token with thewriteoradminscope that isn't restricted to repositories; areadtoken gets403 this token needs the write scope.
Access to organization repositories comes from the organization role (members get write, owners and admins get admin), plus any collaborators added under the repository's Settings → Collaborators, which can include people outside the organization and agents. When a repository is created, the organization's other owners and admins get an email, and when one is deleted they are told who deleted it.
Organization secrets
Organization Actions secrets are available to workflows in every repository the organization owns, as ${{ secrets.NAME }}. If a repository has a secret with the same name, the repository's value wins.
Owners and admins (and site administrators) manage them with the CLI or the API; agents can't (403 agents cannot manage secrets). There is no page for them in the web UI yet. Listing, setting and deleting all need a personal access token with the admin scope that isn't restricted to repositories: other tokens get 403 this token needs the admin scope or 403 this token is limited to repositories and can't change account settings.
# Create or update (the value is read from a hidden prompt, stdin or --body)
diffinery secret set NPM_TOKEN --org acme
# List names and when they were updated (values are never returned)
diffinery secret list --org acme
# Delete
diffinery secret delete NPM_TOKEN --org acme
| Method and path | What it does |
|---|---|
GET /api/v3/orgs/{org}/actions/secrets | List secret names and updated_at |
PUT /api/v3/orgs/{org}/actions/secrets/{name} | Create or update; body {"value": "..."}; returns 204 |
DELETE /api/v3/orgs/{org}/actions/secrets/{name} | Delete; returns 204 |
Names are stored in upper case and must match ^[A-Z_][A-Z0-9_]*$ after upper-casing, otherwise the API returns 422 invalid secret name. Values are encrypted at rest. See Secrets and variables for how workflows use them.
Organization agents
An agent can be owned by an organization instead of a person, so it keeps working when people come and go. Owners and admins create one under Settings → Agents by choosing the organization as Owner, or with diffinery agent create review-bot --org acme. An organization agent can only reach that organization's repositories, and its security emails (new tokens, expiring tokens) go to the organization's owners and admins. See Agents.
Organization picture
The organization's picture shows on its page, next to its repositories and in member lists. Without one, Diffinery shows the first letter or digit of the organization's name on a colored background.
Owners change it on the Settings tab, in the Profile picture box:
- Under Upload a new picture, choose a JPEG, PNG or WebP file of up to 5 MB. It is cropped to a centred square; a preview shows the result.
- Click Save picture. You see "Organization picture updated."
- To go back to initials, click Remove picture and confirm "Remove the picture of acme?". You see "Organization picture removed."
Owners and admins (and site administrators) can also change it through the API, with a token that has the write or admin scope and isn't restricted to repositories. The body is the raw image file:
curl -X PUT https://diffinery.com/api/v3/orgs/acme/avatar \
-H "Authorization: Bearer dfy_..." \
--data-binary @logo.png
curl -X DELETE https://diffinery.com/api/v3/orgs/acme/avatar \
-H "Authorization: Bearer dfy_..."
Both return 200 with the picture's URL, for example {"avatar_url": "https://diffinery.com/api/avatars/acme?v=1760350000"} after an upload and {"avatar_url": "https://diffinery.com/api/avatars/acme"} after removing it. Errors include 403 only organization owners and admins can change its picture for members, and 404 not found when you aren't in the organization. See Profile and preferences for the limits, error messages, the public picture URL and caching.
Rename an organization
Owners open the Settings tab, change Organization name or Display name and click Save. You see "Organization updated." Renaming changes every repository URL in the organization, so existing clones need a new remote URL:
git remote set-url origin https://diffinery.com/acme-inc/website.git
URLs with the old name stop working right away; Diffinery doesn't redirect them.
Organizations API
| Method and path | Description |
|---|---|
GET /api/v3/user/orgs | Organizations you belong to, each with your role |
POST /api/v3/user/orgs | Create an organization: {"login": "acme", "name": "Acme Inc."}. Needs an admin token. |
GET /api/v3/orgs/{org}/members | Members and their roles. Members and site administrators only; others get 404. |
POST /api/v3/orgs/{org}/invitations | Invite by email: {"email": "...", "role": "member"}. Needs an admin token. See Invitations. |
GET /api/v3/orgs/{org}/repos | Repositories you can see in the organization |
POST /api/v3/orgs/{org}/repos | Create a repository in the organization. Needs a write or admin token. |
GET, PUT, DELETE /api/v3/orgs/{org}/actions/secrets[/{name}] | Organization secrets. Needs an admin token. |
PUT /api/v3/orgs/{org}/avatar | Upload the organization's picture (raw image body). Owners and admins. |
DELETE /api/v3/orgs/{org}/avatar | Remove the organization's picture. Owners and admins. |
Organization objects in API responses follow GitHub's shape, with "type": "Organization", html_url and avatar_url.
Every endpoint in this table that changes something is an account-level action: besides the scope noted, the token must not be restricted to repositories, or the request gets 403 this token is limited to repositories and can't change account settings (the picture endpoints answer 403 changing a profile picture needs a write or admin token that is not limited to repositories). See Personal access tokens.
Adding existing people directly, changing a member's role, removing a member and revoking invitations are done in the web UI. The full list of endpoints is in the API reference.
How organizations differ from GitHub
- Diffinery has three organization roles: owner, admin and member. Admins manage members, invitations, agents and secrets but can't manage owners or open the organization's Settings tab.
- Members get write access to every organization repository. GitHub's default base permission is configurable; Diffinery's is fixed.
- There are no teams. Give extra access per repository under Settings → Collaborators.
- Add people works like GitHub's: enter a username or an email address. Unlike GitHub, someone who already has an account joins immediately, with no invitation to accept; only email addresses without an account get an invitation.
- Organization pages need you to be signed in.
- Organization secrets apply to every repository in the organization; there is no per-repository selection.