Skip to content

Commit e17d0c9

Browse files
committed
docs: Clarify JSON serialization
1 parent e434611 commit e17d0c9

File tree

2 files changed

+97
-11
lines changed

2 files changed

+97
-11
lines changed

ARCHITECTURE.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,18 @@ they do not live in `credentialsd-common`).
117117
### `credentialsd/src/webauthn.rs`
118118

119119
Types and functions needed to repackage requests from and responses to
120-
JSON-strings according to the [WebAuthn spec](webauthn-3). With one notable
121-
deviation from the spec: Since we use JSON strings for requests and responses,
122-
raw binary fields need to be base64url-encoded strings. It is the
123-
responsibility of the application using this service to de/construct the field
124-
accordingly.
120+
JSON-strings according to the [WebAuthn spec](webauthn-3).
121+
122+
There is one notable deviation from the spec: since we use JSON strings for
123+
requests and responses, raw binary fields need to be base64url-encoded strings.
124+
(See the note on [D-Bus/JSON serialization][dbus-json-serialization] in the API
125+
docs.) It is the responsibility of the application using this service to
126+
de-/construct the field accordingly.
125127

126128
Re-exports many types from `libwebauthn`.
127129

128130
[webauthn-3]: https://www.w3.org/TR/webauthn-3
131+
[dbus-json-serialization]: /doc/api.md#d-busjson-serialization
129132

130133
### `credentialsd/tests`
131134

doc/api.md

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# API Overview
22

33
There are three main API defined by this specification:
4+
45
- [Gateway API](#gateway-api)
56
- [Flow Control API](#flow-control-api)
67
- [UI Control API](#ui-control-api)
@@ -59,6 +60,78 @@ _privileged_ client: a client that is trusted to set any origin for its requests
5960
_relying party_: an entity wishing to auhtenticate a user
6061
_unprivileged client_: a client that is constrained to use a predetermined set of origin(s)
6162

63+
# General Notes
64+
65+
## D-Bus/JSON serialization
66+
67+
> TODO: rename fields to snake_case so that this note is true in all cases.
68+
69+
This API is modelled after the [Credential Management API][credman-api]. The
70+
top-level fields corresponding to `navigator.credentials.create()` and `get()`
71+
are passed as fields in D-Bus dictionaries using snake_case, according to D-Bus
72+
convention.
73+
74+
So where Credential Management takes:
75+
76+
```json
77+
{
78+
"origin": "example.com",
79+
"topOrigin": "example.com",
80+
"password": true
81+
}
82+
```
83+
84+
this API takes:
85+
86+
```
87+
[a{sv}] {
88+
origin: Variant(""),
89+
top_origin: Variant(""), // topOrigin is changed to top_origin
90+
password: Variant(true),
91+
}
92+
```
93+
94+
However, for the complex requests and responses in the WebAuthn `create()` and `get()`
95+
methods, this API passes JSON-encoded data as a string. Field and enum values
96+
inside the JSON string should remain in camelCase.
97+
98+
Additionally, `ArrayBuffer` objects, which are valid in JavaScript but cannot be
99+
serialized in JSON, must be encoded as base64url strings with padding removed.
100+
101+
So if a client passed this in JavaScript:
102+
103+
```javascript
104+
{
105+
"origin": "example.com",
106+
"topOrigin": "example.com",
107+
"publicKey": {
108+
"challenge": new Uint8Array([97, 32, 99, 104, 97, 108, 108, 101, 110, 103, 101]),
109+
"excludeCredentials": [
110+
{"type:" "public-key", "alg": -7}
111+
],
112+
// ...
113+
}
114+
}
115+
```
116+
117+
it would pass this request to this API:
118+
119+
```
120+
[a{sv}] {
121+
origin: Variant(''),
122+
top_origin: Variant(''), // top-level fields topOrigin and publicKey are
123+
public_key: Variant([a{sv}] { // changed to snake_case
124+
registration_request_json: [s] '{ // <- JSON-encoded string
125+
"challenge": "YSBjaGFsbGVuZ2U", // buffer is encoded as base64url without padding
126+
"excludeCredentials": [ // "excludeCredentials" is not changed to snake_case
127+
{"type": "public-key", "alg": -7} // "public-key" is not changed to snake_case
128+
]
129+
// ...
130+
}'
131+
})
132+
}
133+
```
134+
62135
# Gateway API
63136

64137
The Gateway is the entrypoint for public clients to retrieve and store
@@ -95,6 +168,7 @@ CredentialType[s] [
95168
```
96169

97170
#### Request context
171+
98172
> TODO: replace is_same_origin with topOrigin, required if origin is set.
99173
100174
> TODO: Should we say that `origin` will be optional in the future?
@@ -117,6 +191,7 @@ suffix, as defined by the [Public Suffix List][PSL].
117191
[PSL]: https://github.com/publicsuffix/list
118192

119193
#### Credential Types
194+
120195
> TODO: decide on case of strings (snake_case like D-Bus or camelCase like JS?)
121196
122197
Currently, there is only one supported type of `CreateCredentialRequest`,
@@ -138,9 +213,10 @@ corresponds to WebAuthn credentials:
138213
type.
139214

140215
### Response
216+
141217
> TODO: Should we group common types in their own section for reference?
142-
> CredentialType will be referenced in the request and response of both create
143-
> and get methods.
218+
> CredentialType will be referenced in the request and response of both create
219+
> and get methods.
144220
145221
`CreateCredentialResponse` is a polymorphic type that depends on the type of
146222
the request sent. Its `type` field is a string specifies what kind of
@@ -208,6 +284,7 @@ When multiple credential types are specified, the request context applies to
208284
all credentials.
209285

210286
#### Credential Types
287+
211288
> TODO: decide on case of strings (snake_case like D-Bus or camelCase like JS?)
212289
213290
Currently, there is only one supported type of credential, specified by the
@@ -226,9 +303,10 @@ GetPublicKeyCredentialOptions[a{sv}] {
226303
[def-pubkeycred-request-options]: https://www.w3.org/TR/webauthn-3/#dictdef-publickeycredentialrequestoptions
227304

228305
### Response
306+
229307
> TODO: Should we group common types in their own section for reference?
230-
> CredentialType will be referenced in the request and response of both create
231-
> and get methods.
308+
> CredentialType will be referenced in the request and response of both create
309+
> and get methods.
232310
233311
`GetCredentialResponse` is a polymorphic type that depends on the type of the
234312
request sent. Its `type` field is a string specifies what kind of credential it
@@ -419,10 +497,11 @@ The device needs evidence of user presence (e.g. touch) to release the credentia
419497
`value`: No associated value.
420498

421499
#### UsbState::SELECT_CREDENTIAL
500+
422501
> TODO: Change tense of verb to match other states -> SELECTING_CREDENTIAL
423502
424503
> TODO: field names of Credential type are confusing: "name" is an ID, and
425-
> "username" is a name. We should flip them.
504+
> "username" is a name. We should flip them.
426505
427506
Multiple credentials have been found and the user has to select which to use
428507

@@ -468,6 +547,7 @@ ServiceError[?] [
468547
INTERNAL,
469548
]
470549
```
550+
471551
#### ServiceError::AUTHENTICATOR_ERROR
472552

473553
Some unknown error with the authenticator occurred.
@@ -497,6 +577,7 @@ Something went wrong with the credential service itself, not the authenticator.
497577
`type`: `"INTERNAL"`
498578

499579
### HybridState
580+
500581
> TODO: Failed has no reason
501582
502583
```
@@ -588,7 +669,7 @@ Failed to receive a credential from the hybrid authenticator.
588669
> you would normally think as devices. Maybe "sources" works better?
589670
590671
> TODO: CredentialMetadata is a bad name here, since this more corresponds to
591-
the "devices" or "sources" concept. Change to DeviceMetadata?
672+
> the "devices" or "sources" concept. Change to DeviceMetadata?
592673
593674
This retrieves the various "devices" that the user can choose from to fulfill
594675
the request, filtered by the request origin and other request options.
@@ -683,6 +764,7 @@ selects which credential to release based on the authenticator.
683764
### Response
684765

685766
None.
767+
686768
### Errors
687769

688770
TBD.
@@ -754,6 +836,7 @@ authentication methods, and the user's device can offer a consistent user
754836
interface.
755837

756838
So the Credentials API differs from the Secret Service API in two main ways:
839+
757840
- It supports specific credential formats (e.g. WebAuthn/FIDO2 credentials),
758841
rather than general secrets.
759842
- It is primarily focused on authenticating to relying parties.

0 commit comments

Comments
 (0)