Skip to content

Commit ef7d065

Browse files
committed
docs: align guides with Memos 0.31.0-rc.1
1 parent d0433d2 commit ef7d065

45 files changed

Lines changed: 499 additions & 149 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎content/docs/admin/instance-settings.mdx‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,21 @@ Instance settings control authentication, storage, and memo policies. Admins can
77

88
Common areas include:
99

10+
- Instance access policy: public or private access, stored independently of the canonical instance URL.
1011
- General access controls: user registration, password auth, username and nickname changes, week start day, and custom instance profile.
11-
- Storage settings: database, local filesystem, or S3-compatible attachment storage, file path templates, and upload limits.
12+
- Storage settings: named database, local filesystem, or S3-compatible configurations with stable IDs, a default for new uploads, file path templates, and upload limits.
1213
- Memo-related settings: content length limits, double-click editing, and allowed reaction values.
1314
- Notification settings: SMTP email delivery, sender details, reply-to address, and the email test endpoint.
1415
- AI settings: instance-level OpenAI or Gemini providers and speech-to-text transcription defaults.
1516

1617
Tag colors and content-blur rules are user settings in Memos 0.30 and later, not instance settings. See [Tags](/docs/usage/tags).
1718

19+
## Access policy
20+
21+
In 0.31, the `ACCESS` setting determines whether anonymous visitors may read public content. `MEMOS_INSTANCE_URL` supplies the canonical external address and no longer changes an existing access policy. Use [deployment-managed access configuration](/docs/configuration/deployment-configuration#access-policy) when infrastructure should own this setting.
22+
23+
Instance admins manage these policies but do not become members of every Space or gain editing authority over other authors' memos. See [Users & Roles](/docs/admin/users-roles).
24+
1825
## Sensitive settings
1926

2027
Storage, notification, and AI settings can contain credentials. API responses do not return stored S3 secrets, SMTP passwords, or AI provider API keys in plaintext. When updating those settings, submit a new secret only when you intend to replace it.

‎content/docs/admin/users-roles.mdx‎

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,22 @@ title: Users & Roles
33
description: Manage users and permissions.
44
---
55

6-
Memos supports two roles:
6+
Memos has two instance roles: **Admin** and **User**. The first account created during setup becomes an instance admin. Instance admins manage accounts, instance configuration, and access policy.
77

8-
- Admin
9-
- User
8+
## Instance roles and Space roles
109

11-
Admins can create users, update profiles, and manage access. The first account created during setup becomes an admin.
10+
Each [Space](/docs/usage/spaces) has its own accepted **Admin** and **User** memberships. Instance roles and Space roles are independent: an instance User can create and administer a Space, while an instance Admin has no automatic membership in another user's Space.
11+
12+
Space admins manage the Space's metadata, invitations, and members. Neither kind of admin can edit another author's memo, change its visibility or placement, or manage its attachments, relations, or shares. Reading also follows the memo's visibility; instance administration does not grant access to private or members-only content.
13+
14+
## Usernames
15+
16+
Sign-in and username lookup are case-sensitive: `Alice` and `alice` are different spellings. New and renamed usernames must contain 1–36 ASCII letters or digits, with hyphens allowed only inside the name. Underscores, email addresses, and non-ASCII usernames cannot be newly assigned.
17+
18+
Legacy usernames remain addressable with their exact spelling. Spellings outside the new grammar cannot be written as new mentions. See [Authentication](/docs/configuration/authentication) and [Mentions](/docs/usage/reactions-comments#mentions).
19+
20+
## Removing access or accounts
21+
22+
Removing a Space member leaves their contributions in that Space. A Space must always retain an active admin, so assign another admin before removing or archiving the last one.
23+
24+
Deleting an account is blocked while it has active Space memberships, including when the API request sets `force`. Resolve those memberships first. Deleting a Space instead permanently deletes all directly assigned memos; it is not an equivalent way to remove one user's access.

‎content/docs/configuration/authentication.mdx‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Password auth is usually the right starting point when:
3535

3636
Users sign in with their Memos username and password. Archived users cannot sign in. Failed sign-in attempts use the same error message for unknown usernames and wrong passwords, so the login page does not reveal whether a username exists.
3737

38+
### Username spelling
39+
40+
In 0.31, sign-in and lookup use exact-case usernames. `Alice` and `alice` are distinct spellings. New or renamed usernames must contain 1–36 ASCII letters or digits, with hyphens only inside the name. Existing legacy names remain addressable, but unsupported spellings cannot be used for new mentions. When diagnosing a failed sign-in after upgrading, check the stored username and its case before resetting credentials.
41+
3842
### Disable password authentication
3943

4044
Admins can disable password sign-in for regular users after SSO is configured. When password auth is disabled:

‎content/docs/configuration/deployment-configuration.mdx‎

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
title: Deployment-Managed Configuration
3-
description: Manage authentication, storage, notifications, memo behavior, and AI settings from mounted JSON files.
3+
description: Manage access, authentication, storage, notifications, memo behavior, and AI settings from mounted JSON files.
44
category: configuration
55
tags: ["configuration", "self-hosting", "docker", "kubernetes"]
66
difficulty: advanced
77
estimatedTime: 15 minutes
8-
lastUpdated: "2026-07-22"
8+
lastUpdated: "2026-09-06"
99
---
1010

1111
Memos 0.30 and later can load selected configuration from JSON files mounted under `/etc/secrets`. Use this when settings such as SSO, storage credentials, or registration policy should be controlled by Docker Compose, Kubernetes, GitOps, or a secret manager instead of the admin UI.
@@ -74,6 +74,7 @@ Memos scans direct children of `/etc/secrets` and reads only these filename patt
7474
| Resource | Filename | Stable key |
7575
| --- | --- | --- |
7676
| OAuth2 identity provider | `memos-idp-<label>.json` | `uid` |
77+
| Access policy (0.31+) | `memos-instance-setting-access.json` | `ACCESS` |
7778
| General settings | `memos-instance-setting-general.json` | `GENERAL` |
7879
| Storage settings | `memos-instance-setting-storage.json` | `STORAGE` |
7980
| Memo behavior | `memos-instance-setting-memo-related.json` | `MEMO_RELATED` |
@@ -136,6 +137,25 @@ See [Authentication](/docs/configuration/authentication) for provider setup and
136137

137138
Each instance-setting file contains a `key` and the matching settings object. A file supplies the complete effective group: omitted scalar fields use their default values instead of inheriting values from the database. Empty secret fields are also treated as empty values.
138139

140+
### Access policy
141+
142+
In 0.31, use `memos-instance-setting-access.json` to select access independently of the canonical instance URL:
143+
144+
```json
145+
{
146+
"key": "ACCESS",
147+
"accessSetting": {
148+
"accessMode": "INSTANCE_ACCESS_MODE_PRIVATE"
149+
}
150+
}
151+
```
152+
153+
Use `INSTANCE_ACCESS_MODE_PUBLIC` to allow eligible anonymous public reads. The mode must be explicit; an omitted or unspecified mode is rejected. This setting does not revoke existing share links.
154+
155+
Set `MEMOS_INSTANCE_URL` separately to the canonical external HTTP(S) URL. Credentials, queries, and fragments are not allowed. A private instance can have a canonical URL behind a reverse proxy.
156+
157+
The first upgraded startup initializes a missing database access setting from the old URL-based behavior. Later URL changes do not change access. Upgrade every replica before changing the policy; older binaries still infer public access from the URL. See [Upgrading to 0.31](/docs/operations/upgrade#upgrading-to-031).
158+
139159
### General
140160

141161
Use `memos-instance-setting-general.json` with `key: "GENERAL"`. The complete format is shown in the [Docker Compose quick start](#quick-start-with-docker-compose).
@@ -144,28 +164,37 @@ Use `memos-instance-setting-general.json` with `key: "GENERAL"`. The complete fo
144164

145165
### Storage
146166

147-
Storage types are `DATABASE`, `LOCAL`, and `S3`. S3 requires all credential and location fields shown below.
167+
For 0.31, use named entries in `storages` and select one with `defaultStorageId`. Types are `DATABASE`, `LOCAL`, and `S3`. Each entry has a stable ID; existing attachments continue to use the configuration identified at upload time.
148168

149169
```json
150170
{
151171
"key": "STORAGE",
152172
"storageSetting": {
153-
"storageType": "S3",
154173
"filepathTemplate": "assets/{timestamp}_{uuid}_{filename}",
155174
"uploadSizeLimitMb": "30",
156-
"s3Config": {
157-
"accessKeyId": "access-key",
158-
"accessKeySecret": "secret-key",
159-
"endpoint": "https://s3.example.com",
160-
"region": "us-east-1",
161-
"bucket": "memos-assets",
162-
"usePathStyle": false,
163-
"insecureSkipTlsVerify": false
164-
}
175+
"defaultStorageId": "team-assets",
176+
"storages": [
177+
{
178+
"id": "team-assets",
179+
"name": "Team assets",
180+
"type": "S3",
181+
"s3Config": {
182+
"accessKeyId": "access-key",
183+
"accessKeySecret": "secret-key",
184+
"endpoint": "https://s3.example.com",
185+
"region": "us-east-1",
186+
"bucket": "memos-assets",
187+
"usePathStyle": false,
188+
"insecureSkipTlsVerify": false
189+
}
190+
}
191+
]
165192
}
166193
}
167194
```
168195

196+
Keep every configuration referenced by existing attachments when replacing this complete settings group. Changing the default affects new uploads only. Legacy `storageType` and top-level `s3Config` remain supported for compatibility, but new configurations should use the named format. This example requires 0.31; pin the candidate image to `neosmemo/memos:0.31.0-rc.1` when testing it before the stable release.
197+
169198
Only enable `insecureSkipTlsVerify` for a trusted S3-compatible endpoint using a self-signed certificate. It disables TLS certificate verification.
170199

171200
### Memo behavior

‎content/docs/configuration/environment-variables.mdx‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ All flags and their corresponding environment variables:
1717
| `--data` | `MEMOS_DATA` | auto | Data directory |
1818
| `--driver` | `MEMOS_DRIVER` | `sqlite` | Database backend (`sqlite`, `mysql`, `postgres`) |
1919
| `--dsn` | `MEMOS_DSN` | auto | Database connection string |
20-
| `--instance-url` | `MEMOS_INSTANCE_URL` | `` | Public instance URL; empty enables private mode |
20+
| `--instance-url` | `MEMOS_INSTANCE_URL` | `` | Canonical external URL; independent of access policy |
2121
| `--demo` | `MEMOS_DEMO` | `false` | Demo mode |
22-
| `--allow-private-webhooks` | `MEMOS_ALLOW_PRIVATE_WEBHOOKS` | `false` | Allow webhook URLs that resolve to private or reserved IP ranges |
22+
| `--webhook-private-network-allowlist` | `MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST` | empty | Allowed private destinations: exact hostnames, IP addresses, or CIDRs |
23+
| `--allow-private-webhooks` | `MEMOS_ALLOW_PRIVATE_WEBHOOKS` | `false` | Deprecated blanket exception for private webhook destinations |
2324
| `--log-level` | `MEMOS_LOG_LEVEL` | `info` | Log verbosity (`debug`, `info`, `warn`, `error`) |
2425

2526
### Data directory defaults
@@ -36,9 +37,16 @@ When `MEMOS_DRIVER=sqlite` and `MEMOS_DSN` is empty, the database file defaults
3637

3738
### Public and private mode
3839

39-
Since Memos 0.30, an empty `MEMOS_INSTANCE_URL` puts the instance in **private mode**. Anonymous visitors are redirected to sign-in, RSS is unavailable, and anonymous API access is limited to setup, authentication, registration when allowed, and shared-memo routes.
40+
In Memos 0.31, access is controlled by the `ACCESS` instance setting, through `accessSetting.accessMode`:
4041

41-
Set `MEMOS_INSTANCE_URL` to the canonical external URL when you intentionally want public profiles, public memos, Explore, RSS, and other anonymous reads. The value must include the scheme, for example `https://memos.example.com`.
42+
- `INSTANCE_ACCESS_MODE_PRIVATE`: anonymous visitors are sent to sign-in; anonymous API access is limited to endpoints such as setup, authentication, registration when allowed, and explicit shared memos.
43+
- `INSTANCE_ACCESS_MODE_PUBLIC`: eligible public memos, profiles, and Explore can be read anonymously.
44+
45+
Configure access in instance settings or with a [deployment-managed JSON file](/docs/configuration/deployment-configuration#access-policy). It is not a runtime flag or environment variable.
46+
47+
`MEMOS_INSTANCE_URL` supplies the canonical external address, including for a private instance behind a proxy. It must be an absolute HTTP(S) URL without credentials, a query, or a fragment, such as `https://memos.example.com`.
48+
49+
When the access setting is first initialized, Memos preserves the earlier behavior: a configured URL initializes public access; an empty URL initializes private access. Once the setting exists, changing the URL never changes the access policy. See [Upgrading to 0.31](/docs/operations/upgrade#upgrading-to-031).
4250

4351
## Priority order
4452

@@ -50,10 +58,10 @@ An explicit flag always wins over the environment variable for the same setting.
5058

5159
## Practical guidance
5260

53-
- leave `MEMOS_INSTANCE_URL` empty for a private-only instance
54-
- set it to the canonical public URL when you want anonymous public access or when the app sits behind a proxy
61+
- select private or public access explicitly in the `ACCESS` instance setting
62+
- set `MEMOS_INSTANCE_URL` to the canonical external URL when the app sits behind a proxy
5563
- prefer explicit `MEMOS_DRIVER` and `MEMOS_DSN` when you are not using SQLite defaults
56-
- leave `MEMOS_ALLOW_PRIVATE_WEBHOOKS` disabled unless your webhook targets intentionally live on a trusted private network
64+
- allow only required private webhook destinations with `MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST`; leave the deprecated blanket option disabled
5765
- keep secrets such as database credentials outside committed compose files
5866
- treat these values as part of deployment config and back them up accordingly
5967

‎content/docs/configuration/index.mdx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ Memos can be configured through command-line flags, `MEMOS_*` environment variab
1515
| `--data` | `MEMOS_DATA` | data directory |
1616
| `--driver` | `MEMOS_DRIVER` | database backend |
1717
| `--dsn` | `MEMOS_DSN` | database connection string |
18-
| `--instance-url` | `MEMOS_INSTANCE_URL` | public instance URL; empty enables private mode |
18+
| `--instance-url` | `MEMOS_INSTANCE_URL` | canonical external URL; independent of access policy |
1919
| `--demo` | `MEMOS_DEMO` | demo mode |
20-
| `--allow-private-webhooks` | `MEMOS_ALLOW_PRIVATE_WEBHOOKS` | allow webhook URLs that resolve to private or reserved IP ranges |
20+
| `--webhook-private-network-allowlist` | `MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST` | Allowed private destinations: exact hostnames, IP addresses, or CIDRs |
21+
| `--allow-private-webhooks` | `MEMOS_ALLOW_PRIVATE_WEBHOOKS` | deprecated blanket exception for private webhook destinations |
2122
| `--log-level` | `MEMOS_LOG_LEVEL` | log verbosity (`debug`, `info`, `warn`, `error`) |
2223

2324
## Configuration layers
@@ -27,7 +28,7 @@ Memos can be configured through command-line flags, `MEMOS_*` environment variab
2728
- instance settings control storage, registration, and some auth behavior
2829
- reverse proxy settings affect HTTPS, cookie behavior, and public URL correctness
2930

30-
`MEMOS_INSTANCE_URL` is also an access-mode switch in Memos 0.30 and later. Leave it empty for private mode; set it to the canonical external URL to enable anonymous public surfaces such as Explore and RSS.
31+
In Memos 0.31, the `ACCESS` instance setting selects public or private access independently of `MEMOS_INSTANCE_URL`. Set the URL to the canonical external HTTP(S) address, including for private instances behind a proxy. Manage access in instance settings or a [deployment-managed access file](/docs/configuration/deployment-configuration#access-policy).
3132

3233
## Related topics
3334

‎content/docs/configuration/security.mdx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ The JWT secret is auto-generated as a UUID on first run and stored in the databa
1919

2020
## Core recommendations
2121

22-
- leave `MEMOS_INSTANCE_URL` empty for private mode; set it only when anonymous public access is intended and to the canonical URL used by your reverse proxy
22+
- select private access in the `ACCESS` instance setting when anonymous public access is not intended
23+
- set `MEMOS_INSTANCE_URL` to the canonical URL used by your reverse proxy; changing this URL does not change access policy
2324
- disable user registration if your instance is private
2425
- disable public memo visibility if you do not want any public content
2526
- use HTTPS in front of the instance

‎content/docs/configuration/storage.mdx‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ Memos supports three storage backends for attachments:
1111

1212
Storage is usually configured at the instance level rather than purely through startup flags.
1313

14+
## Named storage configurations
15+
16+
In 0.31, storage settings contain named configurations with stable IDs. Choose a default for new uploads. Existing attachments retain their storage ID, so switching the default does not move old files or change where Memos reads them.
17+
18+
Keep configurations that existing attachments still reference, including their credentials and backing objects. A new default is not a storage migration. Legacy settings migrate automatically on upgrade.
19+
20+
API and deployment-file clients should use `storages` and `defaultStorageId`. The older `storageType` and top-level `s3Config` fields remain compatibility fields. See the [deployment configuration example](/docs/configuration/deployment-configuration#storage).
21+
1422
## Database storage
1523

1624
Database-backed attachments are the default.
@@ -52,6 +60,12 @@ certificate verification for that connection, so use it only for an endpoint
5260
you control and trust. Prefer installing a trusted certificate whenever
5361
possible.
5462

63+
### Authenticated delivery
64+
65+
Memos proxies managed S3 files through its file routes and checks authorization there. Range requests support seeking and partial media reads. Managed S3 attachments no longer return presigned object URLs in `externalLink`; clients should use the Memos file route and preserve any share authorization supplied for a shared memo.
66+
67+
Back up all referenced storage configurations alongside the database and file objects. Changing the default storage only affects new uploads.
68+
5569
## Operational reminders
5670

5771
- set an upload limit appropriate for your environment

‎content/docs/deploy/docker-compose.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ docker compose up -d
4949

5050
- keep your data directory on persistent storage
5151
- place Memos behind a reverse proxy for HTTPS
52-
- leave `MEMOS_INSTANCE_URL` empty for private mode, or set it to the canonical public URL to enable anonymous public access
52+
- set `MEMOS_INSTANCE_URL` to the canonical external URL and configure private or public access separately through the [ACCESS setting](/docs/configuration/deployment-configuration#access-policy)
5353
- back up both the database and any local assets if you do not use database-backed attachment storage
5454

5555
## When to add more services

‎content/docs/deploy/docker.mdx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ All `MEMOS_*` variables correspond directly to command-line flags. Common ones:
6767
| `MEMOS_DATA` | `/var/opt/memos` | Data directory |
6868
| `MEMOS_DRIVER` | `sqlite` | Database backend |
6969
| `MEMOS_DSN` | auto | Database connection string |
70-
| `MEMOS_INSTANCE_URL` | `` | Public instance URL; empty enables private mode |
70+
| `MEMOS_INSTANCE_URL` | `` | Canonical external URL; independent of access policy |
7171
| `MEMOS_DEMO` | `false` | Demo mode |
72-
| `MEMOS_ALLOW_PRIVATE_WEBHOOKS` | `false` | Allow webhook URLs that resolve to private or reserved IP ranges |
72+
| `MEMOS_WEBHOOK_PRIVATE_NETWORK_ALLOWLIST` | empty | Exact hostnames, IP addresses, or CIDRs allowed as private webhook destinations |
73+
| `MEMOS_ALLOW_PRIVATE_WEBHOOKS` | `false` | Deprecated blanket exception for private webhook destinations |
7374
| `MEMOS_LOG_LEVEL` | `info` | Log verbosity (`debug`, `info`, `warn`, `error`) |
7475

7576
Typical example:
@@ -86,7 +87,7 @@ docker run -d \
8687
neosmemo/memos:stable
8788
```
8889

89-
The quick-start command at the top of this page omits `MEMOS_INSTANCE_URL`, so it runs in private mode. The example above enables public mode and anonymous public surfaces by setting the canonical external URL.
90+
On a fresh instance, the quick-start command initializes private access because it omits `MEMOS_INSTANCE_URL`. A configured URL initializes public access only when the access setting does not yet exist. In 0.31, select the desired `ACCESS` policy in instance settings or [deployment configuration](/docs/configuration/deployment-configuration#access-policy); changing the URL of an existing instance does not change that policy.
9091

9192
## External databases
9293

0 commit comments

Comments
 (0)