# Organization administration

What an organization's owners and admins can see and change about the organization
itself, from **Settings**. Each section says who may use it, because the answer differs
and the server, not the screen, decides it.

## Audit log

**Settings › Audit log** lists this organization's audit trail, newest first: who acted,
what they did, to what, from which address, and when. Each row is written as one
sentence, the same sentence the accountability ledger uses, with the raw action name and
result beneath it.

**Who can open it:** organization **owners** only (`org:admin`). An admin, member,
viewer or billing user gets a 403, and the screen shows that refusal rather than an
empty list. A page of the log is a page of every member's IP addresses and browsers, so
it is gated the way the SIEM sinks and data-subject requests are. The machine export
below is gated more loosely, on `read`, because a script holding a member's token could
already pull it.

**Filters:**

| Filter | Matches |
| --- | --- |
| Who | A member. Also matches what an agent did **on that person's behalf**. |
| Action | An action name exactly (`team.create`), or a prefix ending in `*` (`team.*`). Any other `*`, `%` or `_` is refused, not read as a pattern. |
| Target type, Target id | The object acted on, as recorded (`project`, `team`, `org`, …). |
| From, To | Whole days in your time zone. `To` includes the whole day you pick. |
| Only actions taken by the deployment operator | See below. |

**Rows the deployment operator wrote.** When the people who run this Bucker deployment
change something in your organization from their console, two audit rows are written:
one in their own organization and one in yours, in your vocabulary
(`project.ingest.suspended`), carrying `byDeploymentOperator: true`. Those rows are
marked **By deployment operator** here. There is no impersonation: the operator's own
name is the actor.

**Not plan-gated.** The browser works on every plan, Free included, so that those
operator rows are always readable. The export is the paid feature.

**Reading it is recorded.** Every page served writes an `audit.browse` row (who, which
filters, how many rows), after the page is read, so it appears at the top of the next
one. The screen only asks for a page when you press **Apply filters** or **Load older
records**, never in the background.

**Download.** The **Audit-log export** card under the list downloads the same rows as
JSON Lines for a date range. It needs a paid plan (the `auditApi` feature).

### The API

```
GET /orgs/:orgSlug/compliance/audit-log
    ?actor=<principalId>&action=<name|prefix*>&targetType=&targetId=
    &from=<ISO>&to=<ISO, exclusive>&operator=true&cursor=&limit=<1..200, default 50>
```

Answers `{ entries: [...], nextCursor }`, newest first. `nextCursor` is null once the
filter is exhausted; pass it back as `cursor` with the same filters for the next, older
page. Each entry carries `actor` and `onBehalfOf` as `{ principalId, displayName, kind }`
(`displayName` is null when the principal no longer exists), `outcome`
(`APPROVAL` / `DECLINE` / `NEUTRAL`, the accountability ledger's classification), the
`ipAddress`, `userAgent`, `metadata` and `byDeploymentOperator`. `from` must be earlier
than `to`. A malformed cursor is a 400.

For bulk, oldest-first pulls into a SIEM, use `GET /orgs/:orgSlug/compliance/audit-log/export`
(JSON Lines) or a streaming sink instead.

## Teams: the roster and team roles

**Settings › Teams › Roster** opens a team's detail: everyone on it with their team role
and the organization role it sits under, the projects the team is linked to, and the
ownership rules that name the team.

Teams decide which projects members below admin can reach, and a team has two roles:

| Team role | What it adds |
| --- | --- |
| Contributor | Reads and triages the team's projects. |
| Team admin | Manages the team (rename, members, roles) and **administers** its projects. |

**Who can change roles:** an organization owner or admin, or that team's own team admin.
A contributor cannot promote anyone, themselves included. A team admin can step down,
and the change takes effect on their next request, without signing out.

**Who can be a team admin:** a person whose organization role is Owner, Admin or Member.
A Viewer or Billing seat is refused, whether added as team admin or promoted to it:
team admin administers projects, which those roles do not allow. Raise the organization
role first, in **Members**. Agents cannot be team admins. The rule holds both ways:
lowering a team admin's organization role to Viewer or Billing makes them a contributor
on every team they administered, in the same change, and the `org.member.role_change`
audit row lists those teams (`teamAdminCappedTeamIds`). They stay on the teams. Raising
the organization role again does not restore the team role; promote them in the roster.

**Tokens:** a personal access token can only grant a team role whose permissions it
carries itself, so a token cannot create a team admin. Use a signed-in session.

Every change writes a `team.member.role_change` audit row with the role before and
after; adds and removals write `team.member.add` and `team.member.remove`.

**Owned paths** lists only rules on projects you can see yourself; a team you can read
does not show you another project's paths.

### The API

```
GET   /orgs/:orgSlug/teams/:teamSlug/members                  any org member
POST  /orgs/:orgSlug/teams/:teamSlug/members                  { userId, role? }  (role defaults to CONTRIBUTOR)
PATCH /orgs/:orgSlug/teams/:teamSlug/members/:principalId     { role: "TEAM_ADMIN" | "CONTRIBUTOR" }
GET   /orgs/:orgSlug/teams/:teamSlug/ownership                rules naming the team, on projects you can read
```
