Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions content/docs/(reference)/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@ Each release of Marfa ships the server and its container image, the CLI for macO

**Until the first public release, Marfa does not upgrade a database in place.** A build refuses a database whose schema differs from its own or that holds retired tables or settings, and leaves the file unchanged. If the build refuses your database, [Upgrade](/guides/upgrade) covers exporting with the old build and restoring into fresh storage. A version change alone does not cause a refusal.

## v0.0.19

Released October 21, 2026. [v0.0.19 on GitHub](https://github.com/withmarfa/marfa/releases/tag/v0.0.19)

For running an instance:

- **The owner has General and Health pages.** General, at `/auth/owner/general`, shows the instance's name and the five retentions that change while the server runs, and saves only the ones you changed. Health, at `/auth/owner/health`, shows whether the database, saving changes, disk and file storage are working, and the object store when one is attached. It lists every housekeeping job with when it last ran, its error if it failed, and Run now. [Change settings while it runs](/guides/settings#change-settings-while-it-runs) and [Housekeeping](/guides/housekeeping) cover them.
- **The owner has Connected apps and Browsers pages.** Connected apps, at `/auth/owner/apps`, lists the apps you approved, what each can reach, and the keys it made. Disconnecting an app ends its sign-in at once, and its keys keep working unless you also revoke them there. Browsers, at `/auth/owner/browsers`, lists where you are signed in, and signs out one other browser or all of them. Disconnecting an app and signing out another browser need a sign-in within the last five minutes, and the page asks you to confirm it's you if yours is older. [Revoke access](/guides/authenticate#revoke-access) covers apps, and [Sign in as the owner](/guides/authenticate#sign-in-as-the-owner) covers browsers.
- **The owner has Activity and All settings pages.** Activity, at `/auth/owner/activity`, lists the [audit log](/guides/audit-log) newest first and filters it by kind, time and text. All settings, at `/auth/owner/settings`, lists every environment setting by group with its variable, whether it can change while the server runs, and its value now. A setting that holds a secret shows only whether it is set.
- **Eight more settings count as secrets.** `S3_ENDPOINT`, `S3_ACCESS_KEY_ID`, `ERROR_WEBHOOK_URL`, `MARFA_HEARTBEAT_URL`, `OTEL_EXPORTER_OTLP_ENDPOINT`, `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` and `MARFA_POSTHOG_HOST` can carry a credential in an address, so no page shows their value and a startup message that names one no longer prints it. `MARFA_AUTH_BASE_URL` stays readable and the server now refuses one that has a user name, password or query string. [Authentication](https://github.com/withmarfa/marfa/blob/main/conformance/spec/authentication.md#authenticationconsole-settings-no-secret) holds the rule.
- **The owner has Export and restore and Connectors pages, and the Manage and Restore pages are gone.** Export and restore, at `/auth/owner/export`, downloads an archive of everything or of one type and the types under it, with or without file bytes, and restores one. Connectors, at `/auth/owner/connectors`, lists each connector as Failing, Problems, Not heard from for over a day, or Running, shows its recent runs, and clears its saved state or removes it after you confirm. `/auth/owner/manage` and `/auth/owner/restore` no longer exist, and nothing redirects from them to the new pages. [Export an archive](/guides/back-up-and-restore#export-an-archive) and [Restore an archive](/guides/back-up-and-restore#restore-an-archive) cover them.

For apps and devices:

- **`PATCH /config` changes only the settings it names.** A setting in the body is replaced, a setting set to `null` is removed so its default applies, and every other setting stays. `enforcement` is one setting, so a patch that names it replaces all three levers. It takes the same fields and refusals as `PUT /config`. `marfa config update` sends it, with `--body` or `--file`. [Update the configuration](/guides/settings#update-the-configuration) covers it.
- **`GET /audit` filters by `kind` and `q`.** `kind` is one of `access`, `data`, `settings` and `housekeeping`, and each entry is of exactly one kind. `q` keeps the entries that hold every word you give, in any order, ignoring ASCII case. Any other `kind` is refused `400 validation_error`. `marfa audit` doesn't take either yet. [Filter it](/guides/audit-log#filter-it) covers them.
- **`GET /export?format=archive&files=false` leaves out file bytes.** The archive carries no file, and its manifest names each file it would have carried under `missing_blobs`. A restore of it reports those files in `blobs_missing` when the instance doesn't hold them. `marfa export` has no option for it yet. [Leave out the files](/guides/back-up-and-restore#leave-out-the-files) covers it.

## v0.0.18

Released October 20, 2026. [v0.0.18 on GitHub](https://github.com/withmarfa/marfa/releases/tag/v0.0.18)
Expand Down
8 changes: 7 additions & 1 deletion content/docs/guides/audit-log.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@ Authorization: Bearer <key>

Without `--json`, the CLI prints one line for each entry: its ID, action and time.

**The owner can also read the log in a browser.** The Activity page, at `/auth/owner/activity`, lists the entries newest first and filters them by kind, time and text.

## Filter it

Five filters narrow the log, and you can combine them:
Seven filters narrow the log, and you can combine them:

- `action` keeps the entries with this action.
- `resource_type` keeps the entries about this kind of thing.
- `resource_id` keeps the entries about the thing with this ID.
- `created_after` and `created_before` keep the entries recorded between two times, not counting an entry at either time itself.
- `kind` keeps the entries of one kind. Each entry is of exactly one: `access` is sign-ins, keys, folders and the owner's profile, `data` is items, edges, types, files and restores, `settings` is the configuration, webhooks and connectors, and `housekeeping` is what Marfa does on its own. Any other value is refused `400 validation_error`.
- `q` keeps the entries that hold every word of its text, in any order and ignoring ASCII case, in their action, resource, key, address or details.

To see what happened to one item, filter by its ID:

Expand All @@ -92,6 +96,8 @@ Authorization: Bearer <key>
01a12312-d8f0-7301-94a8-558a479db26c item.create 2026-10-09T23:50:00.178Z
```

`marfa audit` takes the first five of these and not `kind` or `q`. [The audit kinds](https://github.com/withmarfa/marfa/blob/main/conformance/spec/events.md#eventsaudit-kind) and [the search](https://github.com/withmarfa/marfa/blob/main/conformance/spec/events.md#eventsaudit-search) hold the rules.

**There is no filter for `key_id`**, so to see what one key did, read the entries and compare their `key_id`.

A page holds 50 entries unless `limit` asks for up to 200. When more match, the answer carries a `next_cursor`: send it back as `cursor` (or `--cursor`) for the next page, and stop when it's `null`. **Marfa refuses a query key it doesn't know** with `400 validation_error`, so a misspelled filter never reads as one that matched everything.
Expand Down
20 changes: 18 additions & 2 deletions content/docs/guides/authenticate.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,23 @@ A program that makes the same request, with no page to show a dialog, gets `403

## Start from Home

**Open the instance's address in a browser where you are signed in as the owner, and Home answers.** It is headed by the instance's name and address, and it lists the owner's pages in groups. A page that needs a look appears under Needs attention. Home has a search that finds a page or a setting by name, which Cmd-K on a Mac or Ctrl-K elsewhere also opens, and a Sign out button. The older management page, at `/auth/owner/manage`, still holds what the newer pages don't: server health, housekeeping, signed-in browsers, connected apps, connectors, and a link to restoring an archive. Home is never cached, because it belongs to the owner.
**Open the instance's address in a browser where you are signed in as the owner, and Home answers.** It is headed by the instance's name and address, and it lists the owner's pages in groups. A page that needs a look appears under Needs attention. Home has a search that finds a page or a setting by name, which Cmd-K on a Mac or Ctrl-K elsewhere also opens, and a Sign out button. Home is never cached, because it belongs to the owner.

Home lists these pages:

| Group | Page | Address | What the owner does there |
| --- | --- | --- | --- |
| Access | API keys | `/auth/owner/keys` | Makes, narrows and revokes keys. [Manage keys](/guides/manage-keys#use-the-api-keys-page) covers it. |
| Access | Connected apps | `/auth/owner/apps` | Sees what each approved app can reach and the keys it made, and disconnects it. [Revoke access](#revoke-access) covers it. |
| Access | Browsers | `/auth/owner/browsers` | Sees where the owner is signed in, and signs out another browser or every other one. [Sign in as the owner](#sign-in-as-the-owner) covers it. |
| Your data | Export and restore | `/auth/owner/export` | Downloads an archive and restores one. [Back up and restore](/guides/back-up-and-restore) covers it. |
| Connections | Connectors | `/auth/owner/connectors` | Sees each connector's state and recent runs, clears its saved state or removes it. |
| This Marfa | General | `/auth/owner/general` | Changes the name and the retentions. [Settings](/guides/settings#change-settings-while-it-runs) covers it. |
| This Marfa | Health | `/auth/owner/health` | Sees whether Marfa's own checks pass, and runs a [housekeeping job](/guides/housekeeping). |
| This Marfa | Activity | `/auth/owner/activity` | Reads the [audit log](/guides/audit-log). |
| This Marfa | All settings | `/auth/owner/settings` | Reads every [environment setting](/guides/settings#every-environment-setting) and its current value. A secret shows only whether it is set. |
| You | Profile | `/auth/owner/profile` | Changes the owner's name and email. |
| You | Password and passkeys | `/auth/owner/passkeys` | Changes the password and manages passkeys. |

**A browser that isn't signed in sees a page that says the instance is running**, with a Sign in link, at `/`. **An owner page sends it to sign in, and back.** Opening an owner page, one under `/auth/owner/`, without a session answers `302` to `/auth/sign-in` with the page you asked for as `return_to`, and signing in returns you there. A page address longer than 2,048 characters returns you to Home instead. On an instance with no owner yet, the redirect goes to `/setup`. A program gets no redirect: a request with an `Authorization` header, or one that doesn't ask for HTML, is answered as before, and `GET /` for a program is still the instance's description.

Expand Down Expand Up @@ -329,7 +345,7 @@ Content-Type: application/x-www-form-urlencoded
token=marfa_rt_…&token_type_hint=refresh_token&client_id=<client_id>
```

Marfa answers `200`, even for a token it doesn't hold. The owner can also disconnect an app in the browser, and a credential holding `grants.manage` lists the apps signed in with `GET /auth/grants` and ends one with `DELETE /auth/grants/{id}`.
Marfa answers `200`, even for a token it doesn't hold. The owner can also disconnect an app on the Connected apps page, which asks whether to revoke the keys the app made too, and a credential holding `grants.manage` lists the apps signed in with `GET /auth/grants` and ends one with `DELETE /auth/grants/{id}`.

**Disconnecting an app from a browser needs a sign-in within the last five minutes.** A browser that signed in earlier is asked to [confirm it's the owner](#confirm-its-you) first, and a request without a page is refused `403 forbidden` and leaves the app working. A credential holding `grants.manage` is not affected by when the owner last signed in, and neither is the private local command.

Expand Down
15 changes: 15 additions & 0 deletions content/docs/guides/back-up-and-restore.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ The [deployment guide](https://github.com/withmarfa/marfa/blob/main/deploy/READM

**An archive holds what its caller can read.** A live owner browser session can export without a key or recent reauthentication. For automated exports with the CLI, make a key that reads everything and use it only for exports. The steps below use that key.

**The owner can also export in a browser.** Export and restore, at `/auth/owner/export`, downloads an archive of everything, or of one type and the types under it, and an Include files switch leaves the files out.

<Steps>
<Step>

Expand Down Expand Up @@ -140,6 +142,17 @@ A file item can name bytes the instance has no record of, as after a restore tha

A store that fails, or doesn't answer within 15 seconds, is not a lost file. The export, or a restore, is refused with `503 blob_store_unavailable` before anything is written, unless another store holds the blob whole. **Try again once the store answers.**

### Leave out the files

**An archive without file bytes is much smaller than one with them.** Add `files=false` to the export, or turn off Include files on the Export and restore page:

```http
GET /export?format=archive&files=false
Authorization: Bearer <key>
```

The archive then carries no file, and its manifest names each file it would have carried under `missing_blobs`. A restore of it reports in `blobs_missing` each of those files that the instance it restores into doesn't hold. `marfa export` has no option for it, and `format=ndjson` carries no file bytes either way. [Export without files](https://github.com/withmarfa/marfa/blob/main/conformance/spec/search-and-filters.md#search-and-filtersexport-without-files) holds the rule.

### What an export checks

**An export isn't taken at one instant**: an item created while it runs may not be in it. Stop your apps first if the archive must hold every write.
Expand All @@ -163,6 +176,8 @@ A [source filter](/guides/settings#what-the-enforcement-levers-do) leaves items
marfa --socket /srv/marfa/data/control/marfa.sock restore marfa-archive.tar.gz
```

**In a browser, restore from the Export and restore page**, at `/auth/owner/export`: choose the archive and select Restore. A sign-in older than five minutes is asked to confirm it's the owner before the upload starts, and the page reports how many items, links, files and types it added.

The answer counts what the restore did. Into a fresh instance:

```json
Expand Down
2 changes: 1 addition & 1 deletion content/docs/guides/housekeeping.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description: See the work an instance does on itself, read what each housekeepin

An instance looks after itself on a schedule: it purges the bin, thins old versions, moves expired feed items to the bin, clears old log entries, sends webhook deliveries, and copies and checks blobs. Each piece of that work is a housekeeping job, and one scheduler runs them all from one table. Reading what each job last did is how you check that an instance is keeping up, and running one yourself applies a new retention without waiting for its schedule.

**Listing needs the `instance.read` permission, and running needs `instance.maintain`.** These permissions apply to housekeeping operations. Item routes use their own permissions. The owner needs no key for either, through the private socket or signed in to the instance's Manage Marfa pages.
**Listing needs the `instance.read` permission, and running needs `instance.maintain`.** These permissions apply to housekeeping operations. Item routes use their own permissions. The owner needs no key for either, through the private socket or signed in to the Health page, at `/auth/owner/health`, which lists every job with when it last ran and its error if it failed, and runs one with Run now.

## List the housekeeping jobs

Expand Down
Loading
Loading