Skip to content

Commit 38e2516

Browse files
committed
fix(auth): harden OAuth provider and API DX
1 parent d51d646 commit 38e2516

131 files changed

Lines changed: 5480 additions & 1069 deletions

File tree

Some content is hidden

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

apps/docs/content/docs/cli/audit-logs.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Every command below also accepts the [global options](/cli/commands#global-optio
1515
sim audit-logs get <auditLogId> [options]
1616
```
1717

18-
Get Audit Log (personal API key required)
18+
Get Audit Log (OAuth login or personal API key required)
1919

2020
**Arguments**
2121

@@ -33,7 +33,7 @@ Get Audit Log (personal API key required)
3333

3434
| Option | Required | Description |
3535
| --- | --- | --- |
36-
| `--organization <value>` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (personal API key required). |
36+
| `--organization <value>` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (OAuth login or personal API key required). |
3737

3838
</CommandTable>
3939

@@ -43,7 +43,7 @@ Get Audit Log (personal API key required)
4343
sim audit-logs list [options]
4444
```
4545

46-
List Audit Logs (personal API key required)
46+
List Audit Logs (OAuth login or personal API key required)
4747

4848
**Options**
4949

@@ -59,8 +59,8 @@ List Audit Logs (personal API key required)
5959
| `--include-departed` | No | Include actions by users who have left the organization. |
6060
| `--no-include-departed` | No | Send --include-departed as false. |
6161
| `--limit <n>` | No | Maximum items to return (0 for everything). Defaults to `100`. |
62-
| `--organization <value>` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (personal API key required). |
62+
| `--organization <value>` | No | Organization ID; defaults to your only organization, and is required when your account belongs to more than one (OAuth login or personal API key required). |
6363
| `--actor-email <value>` | No | Filter by actor email address. |
64-
| `--all-workspaces` | No | Do not filter to the configured workspace (personal API key required for account-wide access). |
64+
| `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). |
6565

6666
</CommandTable>

apps/docs/content/docs/cli/authentication.mdx

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,12 @@ Waiting for you to approve in the browser…
3131
No default workspace. Set one with: sim configure --set-workspace <id>
3232
```
3333

34-
This is OAuth 2.1 with PKCE and a loopback redirect, the same flow the AWS, Google
35-
Cloud, and Cloudflare CLIs use. The browser only ever carries a one-time code;
34+
This is the OAuth 2.0 authorization-code flow with PKCE and a loopback redirect,
35+
aligned with current OAuth security guidance. The browser only ever carries a one-time code;
3636
the tokens are exchanged over the terminal's own connection and written to
3737
`~/.sim/credentials` with `0600` permissions. Access tokens last an hour and are
38-
renewed automatically from a refresh token, so you sign in once and stay signed
39-
in until you log out, revoke the login, or go thirty days without using it. If
40-
it expires, run `sim logout` before signing in again.
38+
renewed automatically from a refresh token. The complete login has a fixed
39+
30-day lifetime; after it expires, run `sim logout`, then sign in again.
4140

4241
<Callout type="warn">
4342
Only approve a consent page you reached by running `sim login` yourself. A
@@ -50,7 +49,7 @@ your login.
5049
| `--no-browser` | Print the URL instead of opening a browser |
5150
| `--browserless` | Use the pairing-code handoff instead (see below) |
5251
| `--read-only` | Ask only for permission to read, never to change anything |
53-
| `--callback-port <port>` | Pin the local port the browser returns to, for a container or SSH session that forwards a fixed one |
52+
| `--callback-port <port>` | Pin the loopback callback port, primarily for an SSH session that forwards the same fixed port |
5453
| `--scope <scope>` | Key space for the pairing-code handoff. Only `copilot` changes anything, and it forces that flow |
5554
| `-y, --yes` | Overwrite an existing API-key profile without prompting |
5655

@@ -92,14 +91,15 @@ the provider switched off; the CLI detects that and falls back on its own.
9291
`--read-only` and `--callback-port` belong to the browser login and have no
9392
meaning here, so combining either with the handoff stops the login rather than
9493
storing a credential you did not ask for. If your SSH session forwards a port
95-
back to your machine, pass `--callback-port <port>` on its own: naming the port
96-
tells the CLI the loopback redirect does reach you, and it runs the browser
97-
login instead of the handoff.
94+
from the remote loopback interface to the browser's machine, pass that same
95+
`--callback-port <port>` on its own. An ordinary container port publication
96+
cannot reach a listener bound to the container's own loopback interface; use
97+
`--browserless` there.
9898

9999
### Picking a workspace
100100

101-
A login carries the full authority of your account across every workspace you
102-
belong to, so the profile's `workspace` setting only decides the default target.
101+
A normal login can act across every workspace you belong to; `--read-only`
102+
limits it to read operations. The profile's `workspace` setting only decides the default target.
103103
Set it after signing in, or pass `--workspace` per command:
104104

105105
```bash
@@ -147,12 +147,11 @@ sim logout # sign out of Sim and remove the stored login
147147
sim logout --all # remove the profile entirely, including its settings
148148
```
149149

150-
For an OAuth login, `sim logout` revokes the current refresh token and its paired
151-
access token before removing them from disk, so the login cannot renew. An
152-
access token copied before an earlier rotation can remain valid until its
153-
one-hour expiry. For an immediate whole-app cutoff, revoke the grant under
154-
**Settings → Authorized apps**; that removes every access and refresh token for
155-
the app.
150+
For an OAuth login, `sim logout` revokes that login's complete token family
151+
before removing it from disk, including access tokens issued before earlier
152+
rotations. Other machines that ran their own `sim login` remain signed in. To
153+
cut off every independent login for the client, revoke the grant under
154+
**Settings → Authorized apps**.
156155

157156
A workspace profile that shares authentication cannot remove the shared login.
158157
Remove only that local profile with `sim logout --all --profile <name>`, or log
@@ -238,10 +237,9 @@ Save it to avoid repeating the flag:
238237
sim configure --set-endpoint http://localhost:3000 --profile local
239238
```
240239

241-
A self-hosted deployment offers OAuth sign-in by default when authentication is
242-
enabled. Set `OAUTH_PROVIDER_ENABLED=false` on the server to switch it off;
243-
`DISABLE_AUTH=true` also forces it off. In either case the CLI uses the
244-
pairing-code handoff.
240+
A self-hosted deployment offers OAuth sign-in when
241+
`OAUTH_PROVIDER_ENABLED=true` and authentication is enabled. Leave it unset to
242+
use the pairing-code handoff; `DISABLE_AUTH=true` also forces OAuth off.
245243

246244
## Where the login is stored
247245

@@ -267,6 +265,13 @@ or with `--yes`; a live OAuth login must be revoked with `sim logout` before
267265
signing in again. Several `sim` commands running at once share one renewal, so
268266
a parallel shell loop cannot sign itself out.
269267

268+
Run `sim login` separately on each machine. Copying `~/.sim/credentials` copies
269+
one single-use refresh-token family; simultaneous use from both copies is
270+
treated as token replay and revokes that login. If a refresh response is lost
271+
because the process or connection stops, the CLI does not retry the consumed
272+
token: run `sim logout`, then `sim login` again. This fail-closed behavior keeps
273+
a copied token from surviving an ambiguous refresh.
274+
270275
## Organization audit logs
271276

272277
`sim audit-logs` requires a **personal** credential — an OAuth login, or the

apps/docs/content/docs/cli/billing.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ Every command below also accepts the [global options](/cli/commands#global-optio
1313
sim billing status [options]
1414
```
1515

16-
Show billing status and current-period credit usage (credits and storage require a personal API key)
16+
Show billing status and current-period credit usage (credits and storage require an OAuth login or personal API key)
1717

1818
**Options**
1919

2020
<CommandTable>
2121

2222
| Option | Required | Description |
2323
| --- | --- | --- |
24-
| `--all-workspaces` | No | Do not filter to the configured workspace (personal API key required for account-wide access). |
24+
| `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). |
2525

2626
</CommandTable>
2727

@@ -31,7 +31,7 @@ Show billing status and current-period credit usage (credits and storage require
3131
sim billing logs [options]
3232
```
3333

34-
List credit usage events (a personal API key reports only your own events; a workspace API key reports every member's in aggregate, unattributed)
34+
List credit usage events (an OAuth login or personal API key reports only your events; a workspace API key reports every member's in aggregate, unattributed)
3535

3636
**Options**
3737

@@ -44,6 +44,6 @@ List credit usage events (a personal API key reports only your own events; a wor
4444
| `--start-date <value>` | No | Custom period start (ISO 8601). |
4545
| `--end-date <value>` | No | Custom period end (ISO 8601). |
4646
| `--limit <n>` | No | Maximum items to return (0 for everything). Defaults to `100`. |
47-
| `--all-workspaces` | No | Do not filter to the configured workspace (personal API key required for account-wide access). |
47+
| `--all-workspaces` | No | Do not filter to the configured workspace (OAuth login or personal API key required for account-wide access). |
4848

4949
</CommandTable>

apps/docs/content/docs/cli/credentials.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Every command below also accepts the [global options](/cli/commands#global-optio
1515
sim credentials delete <credentialId> [options]
1616
```
1717

18-
Disconnect Credential (personal API key required)
18+
Disconnect Credential (OAuth login or personal API key required)
1919

2020
**Arguments**
2121

@@ -80,7 +80,7 @@ sim credentials list [options]
8080
sim credentials update <credentialId> [options]
8181
```
8282

83-
Update Credential (personal API key required)
83+
Update Credential (OAuth login or personal API key required)
8484

8585
**Arguments**
8686

@@ -123,7 +123,7 @@ Update Credential (personal API key required)
123123
sim credentials create <providerId> [options]
124124
```
125125

126-
Create a service-account credential using its discovered provider schema (personal API key required)
126+
Create a service-account credential using its discovered provider schema (OAuth login or personal API key required)
127127

128128
**Arguments**
129129

@@ -154,7 +154,7 @@ Create a service-account credential using its discovered provider schema (person
154154
sim credentials connect <providerId> [options]
155155
```
156156

157-
Create a short-lived link for connecting an OAuth provider (personal API key required)
157+
Create a short-lived link for connecting an OAuth provider (OAuth login or personal API key required)
158158

159159
**Arguments**
160160

@@ -182,7 +182,7 @@ Create a short-lived link for connecting an OAuth provider (personal API key req
182182
sim credentials reconnect <credentialId>
183183
```
184184

185-
Create a short-lived link for reconnecting an OAuth credential (personal API key required)
185+
Create a short-lived link for reconnecting an OAuth credential (OAuth login or personal API key required)
186186

187187
**Arguments**
188188

apps/docs/content/docs/cli/files.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ sim files share get <fileId>
248248
sim files share set <fileId> [options]
249249
```
250250

251-
Enable or disable sharing for a file (personal API key required)
251+
Enable or disable sharing for a file (OAuth login or personal API key required)
252252

253253
**Arguments**
254254

0 commit comments

Comments
 (0)