Skip to content

Commit 636ce4d

Browse files
dawnhogitbook-bot
authored andcommitted
GITBOOK-703: No subject
1 parent a1010ba commit 636ce4d

File tree

8 files changed

+102
-95
lines changed

8 files changed

+102
-95
lines changed
53.5 KB
Loading
57 KB
Loading
20.9 KB
Loading
116 KB
Loading
59.5 KB
Loading
23.4 KB
Loading
437 KB
Loading

docs/device-manufacturer-guidance/building-a-seam-compatible-smart-lock-api/implementing-authentication.md

Lines changed: 102 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ description: >-
66

77
# Implementing Authentication
88

9-
A Seam integration starts with a user linking their account to your platform. We prefer [OAuth2](https://oauth.net/2/) because it provides a standardized, secure way to authenticate users and issue long-lived tokens while ensuring Seam never needs direct access to a user’s private credentials. A clean OAuth2 implementation is the foundation for a stable, reliable integration.
9+
A Seam integration starts when a user signs in to their device provider and gives your platform permission to access their account. The easiest way to support this is through [OAuth2](https://oauth.net/2/), because it gives users a familiar login screen and lets your API issue secure, long-lasting tokens without exposing passwords.
1010

1111
***
1212

1313
## OAuth2 with Access + Refresh Tokens
1414

1515
Your API should use the standard [OAuth2 Authorization Code flow](https://oauth.net/2/).
1616

17-
#### Authorization Request Example
17+
### 1. Authorization request launches the flow
18+
19+
As the first step, Seam makes a GET request to your authorization URL. This should show the user a login screen from your service.
20+
21+
#### Example authorization request
1822

1923
```http
2024
GET https://api.provider.com/oauth/authorize?
2125
response_type=code&
2226
client_id=seam_prod_123&
23-
redirect_uri=https://connect.getseam.com/oauth/callback&
27+
redirect_uri=https://example.com/oauth_redirect&
2428
scope=locks.read%20locks.write&
2529
prompt=login&
2630
state=xyz123
@@ -34,7 +38,63 @@ GET https://api.provider.com/oauth/authorize?
3438

3539
***
3640

37-
#### OAuth Callback Example
41+
### 2. User login + consent screen
42+
43+
After Seam sends the authorization request in [step 1](implementing-authentication.md#id-1.-authorization-request-launches-the-flow), your service should display a login and consent screen. The user signs in, reviews what Seam will be able to access, and decides whether to continue.
44+
45+
46+
47+
{% columns %}
48+
{% column %}
49+
<figure><img src="../../.gitbook/assets/google sign in copy.png" alt="" width="375"><figcaption><p>Example login screen from Google</p></figcaption></figure>
50+
51+
52+
{% endcolumn %}
53+
54+
{% column %}
55+
<figure><img src="../../.gitbook/assets/image (48).png" alt="" width="375"><figcaption><p>Example consent screen from Google</p></figcaption></figure>
56+
57+
58+
{% endcolumn %}
59+
{% endcolumns %}
60+
61+
Your UI should:
62+
63+
* ask the user to log in
64+
* clearly show what Seam will access
65+
* allow them to approve or deny
66+
67+
This step should feel identical to signing into your own product.
68+
69+
***
70+
71+
### 3. Redirect back to Seam with a code
72+
73+
After approval, redirect the browser back to the provided redirect URL:
74+
75+
```
76+
https://example.com/oauth_redirect
77+
```
78+
79+
Your service must append the authorization code (`code`) and `state`:
80+
81+
```http
82+
https://example.com/oauth_redirect?
83+
code=abc123_code_from_provider&
84+
state=xyz123
85+
```
86+
87+
**Key expectations:**
88+
89+
* the redirect URL must exactly match one that Seam registered with your platform.
90+
* `code` is the temporary value Seam will exchange for tokens.
91+
* `state` must match what Seam originally sent in [Step 1](implementing-authentication.md#id-1.-authorization-request-launches-the-flow).
92+
93+
***
94+
95+
### 4. Exchange the code for tokens
96+
97+
Seam will exchange the authorization code for tokens:
3898

3999
```http
40100
POST https://api.provider.com/oauth/token
@@ -47,9 +107,7 @@ client_id=seam_prod_123&
47107
client_secret=shhh_very_secret
48108
```
49109

50-
#### Token Response Example
51-
52-
Your API should return both `access_token`, `refresh_token`, and a stable user or account ID:
110+
**Expected response:**
53111

54112
```json
55113
{
@@ -61,17 +119,17 @@ Your API should return both `access_token`, `refresh_token`, and a stable user o
61119
}
62120
```
63121

64-
**Requirements:**
122+
**Best practices:**
65123

66124
* `access_token` expires quickly (`1h` is typical)
67125
* `refresh_token` lasts long and is stable
68126
* `user_id` must be stable across all future authentications
69127

70128
***
71129

72-
### Use of Bearer Tokens
130+
### 5. Calling your API with the access token
73131

74-
Seam can call your APIs using the standard `Authorization` header:
132+
Seam can call your APIs using the access token. A common way is to do it using the the standard `Authorization` header:
75133

76134
```http
77135
GET https://api.provider.com/v1/locks/123
@@ -80,23 +138,20 @@ Authorization: Bearer ya29.a0ARt76ExampleAccess
80138

81139
***
82140

83-
### Token Refresh
141+
### 6. Refreshing tokens over time
84142

85-
Seam refreshes tokens frequently and concurrently. Refreshing must not invalidate other live tokens.
143+
Seam refreshes tokens frequently, sometimes from multiple workflows running at once.
86144

87-
#### Refresh Request Example
145+
<pre class="language-http"><code class="lang-http"><strong>POST https://api.provider.com/oauth/token
146+
</strong>Content-Type: application/x-www-form-urlencoded
88147

89-
```http
90-
POST https://api.provider.com/oauth/token
91-
Content-Type: application/x-www-form-urlencoded
92-
93-
grant_type=refresh_token&
94-
refresh_token=1//0exampleRefreshToken&
95-
client_id=seam_prod_123&
148+
grant_type=refresh_token&#x26;
149+
refresh_token=1//0exampleRefreshToken&#x26;
150+
client_id=seam_prod_123&#x26;
96151
client_secret=shhh_very_secret
97-
```
152+
</code></pre>
98153

99-
#### Refresh Response Example
154+
**Expected response:**
100155

101156
```json
102157
{
@@ -108,57 +163,41 @@ client_secret=shhh_very_secret
108163
}
109164
```
110165

111-
**Critical behavior:**
112-
113-
* You may issue a _new_ refresh token, but you must keep the previous one valid until it is used or explicitly expires.
114-
* You should _not_ revoke existing access tokens when a refresh occurs.
166+
#### Key requirements
115167

116-
This guarantees reliability during:
117-
118-
* Parallel background jobs
119-
* Mobile app and cloud usage at the same time
120-
* Long-running lock provisioning tasks
168+
* issue a new access token
169+
* keep existing unexpired access tokens valid
170+
* keep the refresh token usable until Seam rotates it
121171

122172
***
123173

174+
## Additional integration requirements
175+
124176
### Stable User Identifier
125177

126-
Every OAuth interaction must return a stable account-level ID. It should:
178+
Seam needs a permanent, account-level ID in every OAuth response so it can reconnect accounts and avoid duplicates. This ID must:
127179

128-
* Never change for a given user
129-
* Not depend on email address (emails change)
130-
* Not depend on tokens
131-
* Not be session-based
180+
* remain the same for the lifetime of the account
181+
* not depend on email addresses
182+
* not change when tokens or sessions rotate
132183

133-
#### Example
184+
**Example access token response:**
134185

135-
```
186+
```json
136187
{
137-
"user_id": "provider_user_491829"
188+
"user_id": "provider_user_491829", // stable account identifier
189+
"access_token": "ya29.a0ARt76ExampleAccess",
190+
"token_type": "Bearer",
191+
"expires_in": 3600,
192+
"refresh_token": "1//0exampleRefreshToken"
138193
}
139194
```
140195

141-
Seam uses this to:
142-
143-
* Deduplicate reconnections
144-
* Reconnect an account after token expiry
145-
* Maintain mapping between providers and Seam workspaces
146-
147-
#### Example Scenario: Reconnect Flow
148-
149-
| Event | Expected Provider Behavior |
150-
| --------------------- | ------------------------------------------------- |
151-
| User connects account | Returns `user_id = provider_user_491829` |
152-
| User disconnects | No change |
153-
| User reconnects later | Returns the same `user_id = provider_user_491829` |
154-
155-
If it changes, Seam must treat it as a new account — which breaks reconnect flows.
156-
157196
***
158197

159198
### Multiple Redirect URLs
160199

161-
Your OAuth app should allow Seam to register multiple redirect URIs.
200+
Seam generally likes to use separate redirect URIs for production, staging, and local development. It's preferable if your provider allows registering multiple URLs.
162201

163202
**Typical examples:**
164203

@@ -168,51 +207,19 @@ https://staging.connect.getseam.com/oauth/callback
168207
http://localhost:3020/oauth/callback
169208
```
170209

171-
#### Registration Object Example
172-
173-
If your API exposes an endpoint for app registration:
174-
175-
```json
176-
{
177-
"client_id": "seam_prod_123",
178-
"redirect_uris": [
179-
"https://connect.getseam.com/oauth/callback",
180-
"https://staging.connect.getseam.com/oauth/callback",
181-
"http://localhost:3020/oauth/callback"
182-
],
183-
"scopes": ["locks.read", "locks.write"]
184-
}
185-
```
186-
187-
If you allow redirect URLs via dashboard, ensure multiple can be entered without replacing each other.
188-
189210
***
190211

191212
### Token Stability Requirements
192213

193-
Seam often runs concurrent jobs using different access tokens.
194-
195-
#### Correct Behavior
196-
197-
* Token refresh returns a new access token
198-
* Existing unexpired access tokens remain valid
199-
* Refresh token remains usable until explicitly rotated
214+
Seam may refresh tokens from multiple workflows at the same time, so refreshing can’t interrupt active requests.
200215

201-
#### Incorrect Behavior (Do Not Do)
202-
203-
* Refreshing invalidates all previous access tokens
204-
* Refreshing invalidates the previous refresh token immediately
205-
* Refreshing requires user reauthentication
206-
* API responds with 401 after every refresh
207-
208-
#### Why It Matters
209-
210-
Seam must support:
216+
**Requirements:**
211217

212-
* Lock provisioning pipelines
213-
* High-frequency device polling during onboarding
214-
* Parallel credential updates across many devices
218+
* issue a new access token during refresh
219+
* let previously issued, unexpired access tokens keep working
220+
* keep the refresh token valid until Seam rotates it
221+
* do not force the user to sign in again or return 401s after refresh
215222

216-
Breaking token stability results in lockouts, expired access grants, and repeated user re-auth flows.
223+
This protects long-running provisioning jobs, onboarding polling, and parallel credential updates from unexpected failures.
217224

218225
***

0 commit comments

Comments
 (0)