change beacon/sentinel to auth server/auth

This commit is contained in:
Tinnus Napbus 2023-08-21 00:50:58 +12:00
parent c2d5a682d2
commit a43cddfbb5
5 changed files with 1522 additions and 0 deletions

View File

@ -0,0 +1,4 @@
+++
title = "Auth Server"
weight = 999
+++

View File

@ -0,0 +1,300 @@
+++
title = "Overview"
weight = 8
template = "doc.html"
+++
Auth Server and Auth are a pair of Urbit apps that facilitate Urbit
authentication for external web apps. Users of the site `example.com` can login
to their `example.com` accounts with their Urbit ships using the Auth app,
assuming the developers of `example.com` have integrated their site with the
Auth Server app.
These docs primarily deal with the API of the Auth Server app, but first we'll
quickly go over how the system works.
1. A user tries to login to the site `example.com` by entering their ship
`~sampel-palnet`.
2. `example.com` sends an authorization request to their ship `~master` running
Auth Server.
3. Auth Server on `~master` sends the request to the Auth app on
`~sampel-palnet`.
4. Auth on `~sampel-palnet` gets the request and makes an HTTP request for
`http://example.com/.well-known/appspecific/org.urbit.auth.json` and
retrieves an attestation that `~master` is an agent of `example.com`.
5. Auth verifies the signature in the attestation using the pubkey of `~master`
it got from Azimuth, then displays an authorization request for the user
that looks like: ![auth example](https://media.urbit.org/docs/auth/auth-example.png)
6. The user of `~sampel-palnet` clicks "Approve" in Auth.
7. Auth on `~sampel-palnet` sends an update to Auth Server on `~master` saying
the request was approved.
8. Auth Server notifies `example.com` that the request was authorized.
9. `example.com` logs the user in.
## Auth Server Basics
Auth Server is intended to be used via an Eyre airlock. The most common is the
`@urbit/http-api` NPM package, which is documented
[here](/guides/additional/http-api-guide). There are a few airlocks for other
languages too, some of which are listed
[here](https://github.com/urbit/awesome-urbit#http-apis-airlock). Eyre's
interfaces extend Urbit's [poke](/reference/glossary/poke),
[scry](/reference/arvo/concepts/scry) and
[subscription](/reference/arvo/concepts/subscriptions) mechanics to HTTP
clients. You can read more about Eyre [here](/reference/arvo/eyre/guide).
### Actions
There are two actions you can poke into Auth Server: A
[`new`](/reference/additional/auth-server/types#new) action to initiate a new
request, and a [`cancel`](/reference/additional/auth-server/types#cancel) action to
cancel an existing request. The `new` action looks something like this:
```json
{
"new": {
"id": "2321f509-316c-4545-a838-4740eed86584",
"request": {
"ship": "sampel-palnet",
"turf": "example.com",
"user": "foobar123",
"code": 123456,
"msg": "blah blah blah",
"expire": 1679788361389
"time": 1679787461389
}
}
}
```
The [`id`](/reference/additional/auth-server/types#id) field is a random unique
ID for the request, and must be a v4 UUID (variant 1, RFC 4122/DCE 1.1).
The fields in the [`request`](/reference/additional/auth-server/types#request) are as
follows:
- `ship`: The ship you're seeking approval from. Note it does not include the
leading `~`.
- `turf`: Your domain. Note it should not include any path, protocol, port etc.
Just `foo.bar.baz`.
- `user`: This field is *optional*, and should be `null` if you don't use it. If
the account username is not merely the ship name, you might like to include it
here to inform the user.
- `code`: This field is *optional*, and should be `null` if you don't use it.
The main purpose of this code is so the user can easily visually associate a
particular request in Auth with the particular login request on your site.
In theory you use it like two-factor authentication and make them type it into
your site, but you generally shouldn't need to as Urbit networking verifies
provenance of packets.
- `msg`: This field is *optional*, and should be `null` if you don't use it.
This is just a general text field where you can include any extra message you
want. You might like to include things like the IP address of the login
request and the browser it came from. It's up to you.
- `expire`: This is the time the request should expire, in milliseconds since
the Unix epoch. You can have it expire whenever you want, but setting it
unreasonably soon (like seconds) may mean the user can't get to it in time,
especially if there's network latency. At least a few minutes from now is a
good idea.
- `time`: This is the timestamp of the request in milliseconds since the Unix
epoch. You would typically just set it to now.
### Updates
There are two main types of updates you'll receive from Auth Server: an
[`entry`](/reference/additional/auth-server/types#entry) update and a
[`status`](/reference/additional/auth-server/types#status) update. An `entry` update
looks like this:
```json
{
"entry": {
"id": "2321f509-316c-4545-a838-4740eed86584",
"request": {
"ship": "zod",
"turf": "localhost",
"user": "@user123",
"code": 123456,
"msg": "blah blah blah",
"expire": 1667213278424,
"time": 1679787461389
},
"result": "sent"
}
}
```
It contains the [`id`](/reference/additional/auth-server/types#id) and
[`request`](/reference/additional/auth-server/types#request) from the `new` action
above, and additionally shows the initial status in the
[`result`](/reference/additional/auth-server/types#result) field. This will normally
be `"sent"`, unless you set the expiry earlier than *now*, in which case it will
immediately be `"expire"` and Auth Server won't bother sending it to the user.
After it's been sent you'll get [`status`](/reference/additional/auth-server/types#status) updates for it when its status changes. A `status` update looks like:
```json
{
"status": {
"id": "2321f509-316c-4545-a838-4740eed86584",
"result": "yes"
}
}
```
Assuming it was initally `"sent"`, you'll get an update with a `"got"`
[`result`](/reference/additional/auth-server/types#result) when the user receives it
(but hasn't yet approved or denied it). If they approve it, you'll then get a
`"yes"` update, or if they deny it you'll get `"no"`. If it expires before they
receive it or before they approve/deny it, you'll get an `"expire"` update. If
there was an error in them receiving the request or your Auth Server couldn't
subscribe for the result, you'll get an `"error"` update. If you cancelled the
request with a `cancel` action, you'll get an `"abort"` result.
The normal flow is `"sent"` -> `"got"` -> `"yes"`/`"no"`, with
`"expire"`,`"error"` and `"abort"` potentially terminating the flow at any
point. The `"sent"` and `"got"` results are transitional, and the rest are
terminal.
### Subscriptions
Auth Server has a number of different subscription paths, but you'd likely only use
one or two. There are two categories of subscription paths:
[`/new/...`](/reference/additional/auth-server/subs#new) and
[`/init/...`](/reference/additional/auth-server/subs#new). The `/new` paths will
start giving you any updates that occur after you subscribe. The `/init` paths
will do the same, but they'll also give you initial state. For each of these,
there is a path to receive all updates, and there are also sub-paths to filter
by [`turf`](/reference/additional/auth-server/types#turf) (domain),
[`ship`](/reference/additional/auth-server/types#ship) and
[`id`](/reference/additional/auth-server/types#id). Additionally, for each
sub-path, you can specify a "since" time, and only receive updates and
initial state for requests with `time`s *later* than the one you specify.
If you're only handling a single site in Auth Server, you can just subscribe to the
`/init/all` path, retreiving initial state and then further updates as they
occur. If your site loses connection to Auth Server, you can just resubscribe to
`/init/all` to resync state, or, if you don't want all historical state, you
could subscribe to `/init/all/since/1679787461389 ` where the `time`
specified is the oldest time you think you could reasonably care about.
### Attestations
As described at the beginning, Auth checks
`<domain>/.well-known/appspecific/org.urbit.auth.json` to verify a request
actually comes from the domain it claims. That `.json` file must contain a
[`manifest`](/reference/additional/auth-server/types#manifest), which is just an
array of [`proof`](/reference/additional/auth-server/types#proof)s. A `proof` looks
like:
```json
{
"turf": "example.com",
"life": 1,
"ship": "zod",
"sign": "jtvkTK0JMizoY12Kw51R11OSKzmtCt2WHB3ev32R+k32O+Y6rJ7jHtrRizm0/0aKwJIO8X5PbDHwdti296XLCQ=="
}
```
The Auth Server front-end includes a simple tool to generate a `manifest` for a
single domain and ship. You can access it by clicking on Auth Server's tile in
Landscape.
Alternatively, you can make a scry request to the
[`/proof/[turf]`](/reference/additional/auth-server/scry#proof[turf]) scry path and
then programmatically put resulting proof(s) in a `manifest` array and serve
them on the `/.well-known/...` path. The `turf` in the path is your domain.
{% callout %}
[If your domain contains special characters, see the note at the bottom.](#additional note)
{% /callout %}
The `manifest` is allowed to contain multiple proofs for the same ship,
including different `live`s (key revisions), as well as for multiple different
ships and domains. Auth will try find the best case with the following
priority:
1. Valid signature at current life.
2. Invalid signature at current life.
3. Valid signature at previous life.
4. Invalid signature at previous life.
5. Unable to verify it at all.
If it's valid at current life, it will display a green lock icon and say it's
authentic. If it's a valid signature at an old life, it'll show a yellow lock
icon with an alert that it's outdated and may not come from the URL it claims.
Otherwise, it'll show a red unlock icon and a warning that it may not come from
the URL it claims.
If Auth successfully validates a domain for a particular ship, it'll
remember it for 30 days and not bother to revalidate requests during that time.
For any other outcome, it won't remember and will try validate it again the next
time.
When trying to retrieve the `manifest`, Auth will follow up to 5 redirects,
and will retry up to 3 times if it doesn't get a `20x` status response. If it
gets a `20x` response but the manifest is missing or malformed, it will give up
immediately. If there are too many retries, too many redirects, or a `20x`
response is malformed, the request will be shown to the user with a red unlock
icon and a warning as described above.
{% callout %}
Auth cannot follow relative redirect URLs - redirects MUST be absolute URLs
including protocol.
{% /callout %}
## Additional note
The manifest generator along with the `/proof/[turf]` scry path and `turf`
subscription paths expect a domain with only lowercase `a-z`, `0-9`, `-` and
`.` separators. If your domain contains other characters, you'll have to use
the altenative `wood` paths with `++wood` encoding.
Here's an example implementation of `++wood` encoding:
```javascript
// encode the string into @ta-safe format, using logic from +wood.
// for example, 'some Chars!' becomes '~.some.~43.hars~21.'
//
export function stringToTa(str: string): string {
let out = "";
for (let i = 0; i < str.length; i++) {
const char = str[i];
let add = "";
switch (char) {
case " ":
add = ".";
break;
case ".":
add = "~.";
break;
case "~":
add = "~~";
break;
default:
const charCode = str.charCodeAt(i);
if (
(charCode >= 97 && charCode <= 122) || // a-z
(charCode >= 48 && charCode <= 57) || // 0-9
char === "-"
) {
add = char;
} else {
// TODO behavior for unicode doesn't match +wood's,
// but we can probably get away with that for now.
add = "~" + charCode.toString(16) + ".";
}
}
out = out + add;
}
return out;
}
```
You might also like to look at the Hoon reference for the
`++wood` function [here](/reference/hoon/stdlib/4b#wood).

View File

@ -0,0 +1,325 @@
+++
title = "Scry Paths"
weight = 13
template = "doc.html"
+++
Below are all the scry paths you can query. All paths are `%x` scries.
## `/proof/[turf]`
Make a [`proof`](/reference/additional/auth-server/types#proof) for the given
[`turf`](/reference/additional/auth-server/types#turf) (domain). This is put in a
[`manifest`](/reference/additional/auth-server/types#manifest) and published at
`<domain>/.well-known/appspecific/org.urbit.auth.json`. Auth uses it to
validate requests.
#### Returns
A [`proof`](/reference/additional/auth-server/types#proof).
#### Example
```
/proof/example.com
```
---
## `/proof/wood/[turf]`
Make a [`proof`](/reference/additional/auth-server/types#proof) for the given
[`++wood`-encoded](/reference/additional/auth-server/overview#additional-note)
[`turf`](/reference/additional/auth-server/types#turf) (domain). This is put in a
[`manifest`](/reference/additional/auth-server/types#manifest) and published at
`<domain>/.well-known/appspecific/org.urbit.auth.json`. Auth uses it to
validate requests.
#### Returns
A [`proof`](/reference/additional/auth-server/types#proof).
#### Example
```
/proof/example.com
```
---
## `/all`
Get the complete state of all existing requests.
#### Returns
You'll receive an [`initAll`](/reference/additional/auth-server/types#initall) update
containing the current state.
---
## `/all/since/[time]`
Get all requests later than the specified Unix millisecond time, and their
statuses.
#### Returns
You'll receive an
[`initAll`](/reference/additional/auth-server/types#initall) update containing the
current state of requests later than the one specified.
#### Example
```
/all/since/1678658855227
```
---
## `/all/before/[time]`
Get all requests before the specified Unix millisecond time, and their
statuses.
#### Returns
You'll receive an [`initAll`](/reference/additional/auth-server/types#initall) update
containing the current state of requests earlier than the one specified.
#### Example
```
/all/before/1678658855227
```
---
## `/ship/[ship]`
Get the state of all existing requests for the specifed
[`ship`](/reference/additional/auth-server/types#ship).
#### Returns
You'll receive an [`initShip`](/reference/additional/auth-server/types#initship)
update containing all requests for the specified `ship`, and their statuses.
#### Example
Note the leading `~` is omitted:
```
/ship/sampel-palnet
```
---
## `/ship/[ship]/since/[time]`
Get the state of all existing requests for the specifed
[`ship`](/reference/additional/auth-server/types#ship) later than the specified Unix millisecond time.
#### Returns
You'll receive an [`initShip`](/reference/additional/auth-server/types#initship)
update containing all entries for the specified `ship` with `time `s later than
the one specified.
#### Example
```
/ship/sampel-palnet/since/1678658855227
```
---
## `/ship/[ship]/before/[time]`
Get the state of all existing requests for the specifed
[`ship`](/reference/additional/auth-server/types#ship) earlier than the specified Unix millisecond time.
#### Returns
You'll receive an [`initShip`](/reference/additional/auth-server/types#initship)
update containing all entries for the specified `ship` with `time `s before the
one specified.
#### Example
```
/ship/sampel-palnet/before/1678658855227
```
---
## `/turf/[turf]`
Get the state of all existing requests for the specifed
[`turf`](/reference/additional/auth-server/types#turf) (domain).
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/turf/wood/[turf]` path instead.
{% /callout %}
#### Returns
You'll receive an [`initTurf`](/reference/additional/auth-server/types#initturf)
update containing all requests for the specified `turf`, and their statuses.
#### Example
```
/turf/example.com
```
---
## `/turf/[turf]/since/[time]`
Get the state of all existing requests for the specifed
[`turf`](/reference/additional/auth-server/types#turf) (domain) later than the
specified Unix millisecond time.
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/turf/wood/[turf]/since/[time]` path instead.
{% /callout %}
#### Returns
You'll receive an [`initTurf`](/reference/additional/auth-server/types#initturf)
update containing all entries with timestamps later than the one specified.
#### Example
```
/turf/example.com/since/1678658855227
```
---
## `/turf/[turf]/before/[time]`
Get the state of all existing requests for the specifed
[`turf`](/reference/additional/auth-server/types#turf) (domain) earlier than the
specified Unix millisecond time.
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/turf/wood/[turf]/before/[time]` path instead.
{% /callout %}
#### Returns
You'll receive an [`initTurf`](/reference/additional/auth-server/types#initturf)
update containing all entries for the specified `turf` (domain) with timestamps
earlier than the one specified.
#### Example
```
/turf/example.com/before/1678658855227
```
---
## `/turf/wood/[turf]`
Get the state of all existing requests for the specifed
[`turf`](/reference/additional/auth-server/types#turf) (domain), with [`++wood` encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll receive an [`initTurf`](/reference/additional/auth-server/types#initturf)
update containing all requests for the specified `turf`, and their statuses.
#### Example
```
/turf/wood/example~.com
```
---
## `/turf/wood/[turf]/since/[time]`
Get the state of all existing requests for the specifed
[`turf`](/reference/additional/auth-server/types#turf) (domain) later than the
specified Unix millisecond time. With [`++wood`
encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll receive an [`initTurf`](/reference/additional/auth-server/types#initturf)
update containing all entries with timestamps later than the one specified.
#### Example
```
/turf/wood/example~.com/since/1678658855227
```
---
## `/turf/wood/[turf]/before/[time]`
Get the state of all existing requests for the specifed
[`turf`](/reference/additional/auth-server/types#turf) (domain) earlier than the
specified Unix millisecond time. With [`++wood`
encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll receive an [`initTurf`](/reference/additional/auth-server/types#initturf)
update containing all entries for the specified `turf` (domain) with timestamps
earlier than the one specified.
#### Example
```
/turf/wood/example~.com/before/1678658855227
```
---
## `/id/[uuid]`
Get a particular request and its current status, by UUID.
#### Returns
An [`entry`](/reference/additional/auth-server/types#entry) update containing the
request in question and its current status.
#### Example
```
/id/2321f509-316c-4545-a838-4740eed86584
```
---
## `/id/status/[time]`
Get the status of a particular request.
#### Returns
A [`status`](/reference/additional/auth-server/types#status) update containing the status of the request with the specified [`id`](/reference/additional/auth-server/types#id).
#### Example
```
/x/id/status/01a618cc-0c65-4278-853b-21d9e1289b93
```
---

View File

@ -0,0 +1,418 @@
+++
title = "Subscriptions"
weight = 12
template = "doc.html"
+++
Below are all the paths you can subscribe to in Auth Server.
## `/new/...`
Subscription paths beginning with `/new` will not give you any initial state,
you'll just get events that happen after you've subscribed.
### `/new/all`
Subscribe for all new updates.
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur.
---
### `/new/all/since/[time]`
Subscribe for all new updates since the given Unix millisecond time.
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
the occur, but only for those with timestamps later than the one specified.
#### Example
```
/new/all/since/1678658855227
```
---
### `/new/turf/[turf]`
Subscribe for all new updates for the given
[`turf`](/reference/additional/auth-server/types#turf) (domain).
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/new/turf/wood/[turf]` path instead.
{% /callout %}
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
they occur, as long as they're for the specified `turf`.
#### Example
For `example.com`:
```
/new/turf/example.com
```
For `foo.bar-baz.com`:
```
/new/turf/foo.bar-baz.com
```
---
### `/new/turf/[turf]/since/[time]`
Subscribe for all new updates for the given
[`turf`](/reference/additional/auth-server/types#turf) (domain), since the given Unix millisecond time.
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/new/turf/wood/[turf]/since/[time]` path instead.
{% /callout %}
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
they occur, as long as they're for the specified `turf` and their timestamp is
sooner than the one specified in the path.
#### Example
```
/new/turf/example.com/since/1678658855227
```
---
### `/new/turf/wood/[turf]`
Subscribe for all new updates for the given
[`turf`](/reference/additional/auth-server/types#turf) (domain), with [`++wood`
encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
they occur, as long as they're for the specified `turf`.
#### Example
For `example.com`:
```
/new/turf/example~.com
```
For `foo.bar-baz.com`:
```
/new/turf/foo~.bar-baz~.com
```
---
### `/new/turf/wood/[turf]/since/[time]`
Subscribe for all new updates for the given
[`turf`](/reference/additional/auth-server/types#turf) (domain), since the given Unix
millisecond time. With [`++wood`
encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
they occur, as long as they're for the specified `turf` and their timestamp is
sooner than the one specified in the path.
#### Example
```
/new/turf/example~.com/since/1678658855227
```
---
### `/new/ship/[ship]`
Subscribe for all new updates for the given
[`ship`](/reference/additional/auth-server/types#ship).
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
the occur, but only for those that pertain to the specified ship.
#### Example
Note that the ship does not include the leading `~`:
```
/new/ship/sampel-palnet
```
---
### `/new/ship/[ship]/since/[time]`
Subscribe for all new updates for the given
[`ship`](/reference/additional/auth-server/types#ship), since the given Unix millisecond time.
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates for requests as
they occur, as long as they're for the specified `ship` and their timestamp is
sooner than the one specified in the path.
#### Example
Note that the ship does not include the leading `~`:
```
/new/ship/sampel-palnet/since/1678658855227
```
---
### `/new/id/[uuid]`
Subscribe for all new updates for the given
[`id`](/reference/additional/auth-server/types#id).
#### Returns
You'll receive [`entry`](/reference/additional/auth-server/types#entry) updates and
any [`status`](/reference/additional/auth-server/types#status) updates for the
request with the given `id` as they occur.
#### Example
```
/new/id/01a618cc-0c65-4278-853b-21d9e1289b93
```
---
## `/init/...`
Subscription paths beginning with `/init` do the same as [`/new`](#new) except
they also give you initial state when you first subscribe.
### `/init/all`
Subscribe for all new updates, and get the complete existing state of all
requests.
#### Returns
You'll initially receive an
[`initAll`](/reference/additional/auth-server/types#initall) update containing the
current state, and then you'll continue to receive
[`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur.
---
### `/init/all/since/[time]`
Subscribe to updates for requests that occurred after the specified Unix
millisecond time, and get the existing state of all requests with
timestamps later than the one specified.
#### Returns
You'll initially receive an
[`initAll`](/reference/additional/auth-server/types#initall) update containing the
current state of requests later than the one specified. After that, you'll
continue to receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for requests whose timestamps are later than the one given.
#### Example
```
/init/all/since/1678658855227
```
---
### `/init/turf/[turf]`
Get existing request state and subscribe to updates pertaining to the given
[`turf`](/reference/additional/auth-server/types#turf).
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/init/turf/wood/[turf]` path instead.
{% /callout %}
#### Returns
You'll initially receive an
[`initTurf`](/reference/additional/auth-server/types#initturf) update containing the
current state of requests for the given `turf`. After that, you'll continue to
receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for that `turf`.
#### Example
```
/init/turf/example.com
```
---
### `/init/turf/[turf]/since/[time]`
Get existing request state and subscribe to updates pertaining to the given
[`turf`](/reference/additional/auth-server/types#turf), for requests whose timestamps
are later than the Unix millisecond time given.
{% callout %}
If your domain contains characters apart from `a-z`, `0-9`, `-` and `.`
separators, see the `/init/turf/wood/[turf]/since/[time]` path instead.
{% /callout %}
#### Returns
You'll initially receive an
[`initTurf`](/reference/additional/auth-server/types#initturf) update containing the
current state of requests for the given `turf` with times later than the
given one. After that, you'll continue to receive
[`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for that `turf` and have timestamps later than the one
specified.
#### Example
```
/init/turf/example.com/since/1678658855227
```
---
### `/init/turf/wood/[turf]`
Get existing state request state and subscribe to updates pertaining to the
given [`turf`](/reference/additional/auth-server/types#turf). With [`++wood`
encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll initially receive an
[`initTurf`](/reference/additional/auth-server/types#initturf) update containing the
current state of requests for the given `turf`. After that, you'll continue to
receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for that `turf`.
#### Example
```
/init/turf/wood/example~.com
```
---
### `/init/turf/wood/[turf]/since/[time]`
Get existing request state and subscribe to updates pertaining to the given
[`turf`](/reference/additional/auth-server/types#turf), for requests whose timestamps
are later than the Unix millisecond time given. With [`++wood`
encoding](/reference/additional/auth-server/overview#additonal-note).
#### Returns
You'll initially receive an
[`initTurf`](/reference/additional/auth-server/types#initturf) update containing the
current state of requests for the given `turf` with timestamps later than the
given one. After that, you'll continue to receive
[`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for that `turf` and have timestamps later than the one
specified.
#### Example
```
/init/turf/example~.com/since/1678658855227
```
---
### `/init/ship/[ship]`
Subscribe to updates for requests pertaining to the given
[`ship`](/reference/additional/auth-server/types#ship), and get the existing state of
all requests pertaining to that `ship`.
#### Returns
You'll initially receive an
[`initShip`](/reference/additional/auth-server/types#initship) update containing the
current state of requests for the given `ship`. After that, you'll continue to
receive [`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for that `ship`.
#### Example
```
/init/ship/sampel-palnet
```
---
### `/init/ship/[ship]/since/[time]`
Subscribe to updates for requests pertaining to the given
[`ship`](/reference/additional/auth-server/types#ship), and get the existing state of
all requests pertaining to that `ship`, as long as the timestamp is later than
the Unix millisecond time given.
#### Returns
You'll initially receive an
[`initShip`](/reference/additional/auth-server/types#initship) update containing the
current state of requests for the given `ship` with `stamp`s later than the
`stamp` given. After that, you'll continue to receive
[`entry`](/reference/additional/auth-server/types#entry) and
[`status`](/reference/additional/auth-server/types#status) updates as they occur, as
long as they're for that `ship` and have timestamps later than the one
specified.
#### Example
```
/init/ship/sampel-palnet/since/1678658855227
```
---

View File

@ -0,0 +1,475 @@
+++
title = "Types"
weight = 14
template = "doc.html"
+++
## `logs`
A list of [`request`](#request)s, their [`id`](#id)s, and their current
[`result`](#result)s. These are given in the various initialization
[`updates`](#updates).
#### Example
```json
[
{
"id": "7e16a2f5-b955-47c3-b921-da349c0e2c24",
"request": {
"ship": "zod",
"turf": "localhost",
"user": "foobar123",
"code": 123456,
"msg": "blah blah blah",
"expire": 1679820698574,
"time": 1679819798574
},
"result": "yes"
},
{
"id": "d63971cc-453f-49a8-868f-02e2ff768ed2",
"request": {
"ship": "zod",
"turf": "localhost",
"user": "xyz",
"code": 123456,
"msg": null,
"expire": 1679820699556,
"time": 1679819799556
},
"result": "yes"
},
{
"id": "587f6be9-1dca-4310-9239-ea541943f0e0",
"request": {
"ship": "zod",
"turf": "localhost",
"user": null,
"code": null,
"msg": "blah blah blah",
"expire": 1679820700233,
"time": 1679819800233
},
"result": "no"
}
]
```
---
## `manifest`
An array of [`proof`](#proof)s. This is published at
`<domain>/.well-known/appspecific/org.urbit.auth.json`, and then Auth uses
it to validate requests.
#### Example
```json
[
{
"turf": "example.com",
"life": 1,
"ship": "zod",
"sign": "jtvkTK0JMizoY12Kw51R11OSKzmtCt2WHB3ev32R+k32O+Y6rJ7jHtrRizm0/0aKwJIO8X5PbDHwdti296XLCQ=="
}
]
```
---
## `proof`
An attestation that a ship is an agent of a site. An array of such `proof`s are
published at `<domain>/.well-known/appspecific/org.urbit.auth.json` in a
[`manifest`](#manifest), and then Auth uses them to validate requests.
#### Example
```json
{
"turf": "example.com",
"life": 1,
"ship": "zod",
"sign": "jtvkTK0JMizoY12Kw51R11OSKzmtCt2WHB3ev32R+k32O+Y6rJ7jHtrRizm0/0aKwJIO8X5PbDHwdti296XLCQ=="
}
```
## `request`
An authorization request. The `user`, `code` and `msg` fields are all optional
and may be `null` if not used. The `expire` field is the date-time that the
request should expire, as milliseconds since the Unix Epoch. The `time` field
is the timestamp of the request - you'd typically use now.
#### Examples
```json
{
"ship": "zod",
"turf": "example.com",
"user": "foo123",
"code": 1234,
"msg": "blah blah blah",
"expire": 1679820700233,
"time" 1679819800233,
}
```
```json
{
"ship": "zod",
"turf": "example.com",
"user": null,
"code": null,
"msg": null,
"expire": 1679820700233,
"time" 1679819800233,
}
```
---
## `result`
The status of an authorization request. It may be one of:
* `"yes"` - The request was approved.
* `"no"` - The request was denied.
* `"expire"` - The request expired without the user approving or denying it.
* `"got"` - The user's ship received the request, but they have not yet approved
or denied it.
* `"sent"` - Auth Server has sent the request; the user's ship has not yet confirmed
receipt.
* `"abort"` - You have given Auth Server a [`cancel`](#cancel) action, so the request
has been cancelled.
* `"error"` - The request failed. This will occur if the user's ship rejected
the request (nack'd the poke) or Auth Server was unable to subscribe to their ship
for the result. This should not normally occur.
The typical flow is `"sent"` -> `"got"` -> `"yes"` or `"no"`. At any point in
that flow, it may expire in which case you'll get `"expire"` and nothing
further. The transitional states are therefore `"sent"` and `"got"`, with the
remaining being terminal.
---
## `ship`
An Urbit ship. The ship is a string and **does not include the leading ~**.
#### Examples
```json
"zod"
```
```json
"sampel-palnet"
```
```json
"livbes-minwyn-sicmev-halner--soplyt-nimfyl-widnyd-difwyx"
```
---
## `sign`
Ed25519 signature of the domain name with the ship's keys, encoded in a string
as Base64.
This is used in a [`proof`](#proof) to attest that a particular ship is an agent
of a particular site.
#### Example
```json
"jtvkTK0JMizoY12Kw51R11OSKzmtCt2WHB3ev32R+k32O+Y6rJ7jHtrRizm0/0aKwJIO8X5PbDHwdti296XLCQ=="
```
---
## `id`
A request ID. The [`id`](/reference/additional/auth-server/types#id) field is a
random unique ID for the request, and must be a v4 UUID (variant 1, RFC
4122/DCE 1.1).
Note this is decoded into a 122-bit `@ux` atom by `%auth-server` - the UUID form is
only used in JSON, scry paths and subscription paths.
#### Example
```json
"6360904f-7645-4747-91a1-8d7844f11d18"
```
---
## `turf`
A domain. This must be just the domain like `localhost`, `example.com`,
`foo.bar.baz`, etc, without any protocol, forward slashes, port, paths, etc.
---
## Actions
Ask Auth Server to either initiate a new authorization request, or cancel an existing
one. These are given to Auth Server as pokes.
### `new`
Initiate a new authorization request. The `new` action contains a
[`request`](#request) structure and a request [`id`](#id).
#### Example
```json
{
"new": {
"id": "6360904f-7645-4747-91a1-8d7844f11d18",
"request": {
"ship": "zod",
"turf": "localhost",
"user": "foobar123",
"code": 123456,
"msg": "blah blah blah",
"expire": 1679820700233,
"time" 1679819800233
}
}
}
```
### `cancel`
Cancel an existing request. The [`id`](#id) in the ID of the request you
want to cancel.
#### Example
```json
{"cancel": {"id": "6360904f-7645-4747-91a1-8d7844f11d18"}}
```
---
## Updates
The types of event/update that Auth Server can send back to you.
### `entry`
This will be sent back to you whenever you make a new request with a
[`new`](#new) action. It contains the request [`id`](#id),
[`request`](#request) and initial [`result`](#result). The initial result will
typically be `sent`, unless you specified an expiration time before the current
time, in which case it'll be `expire`.
#### Example
```json
{
"entry": {
"id": "6360904f-7645-4747-91a1-8d7844f11d18",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "blah blah blah",
"user": "@user123",
"expire": 1679820700233,
"time" 1679819800233
},
"result": "sent"
}
}
```
### `status`
A `status` update will be sent back whenever the status of a request changes,
for example if the user receives the request, the user approves or denies the
request, the request expires, etc. It contains a request [`id`](#id) and a
[`result`](#result).
#### Examples
```json
{
"status": {
"id": "6360904f-7645-4747-91a1-8d7844f11d18",
"result": "yes"
}
}
```
```json
{
"status": {
"id": "6360904f-7645-4747-91a1-8d7844f11d18",
"result": "got"
}
}
```
### `initAll`
This is sent as the inital update when you first subscribe to one of the
`/init/all/...` paths. It's also returned by some of the scry paths. It
contains existing entries, possibly limited to entries before or after a
specific timestamp.
It contains a [`logs`](#logs) field with the entries themselves, and also
`before` and `after` fields which will either contain Unix millisecond times or
else be null if no such limits were specified.
#### Example
```json
{
"initAll": {
"since": null,
"before": null,
"logs": [
{
"id": "0782ebea-e8d3-4c6a-bf1c-5c336c82a0d3",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "blah blah",
"user": "foobar123",
"expire": 1679827515744,
"time": 1679826615744
},
"result": "yes"
},
{
"id": "4c54c5d9-6584-4d3b-ab62-e55f5f2033c4",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "foo bar baz",
"user": null,
"expire": 1679827571421,
"time": 1679826671421
},
"result": "no"
},
]
}
}
```
### `initTurf`
This is sent as the inital update when you first subscribe to one of the
`/init/turf/...` paths. It's also returned by some of the scry paths. It
contains existing entries for a specific [`turf`](#turf) (domain), possibly
limited to entries before or after a specific timestamp.
It contains a [`turf`](#turf) field showing which domain it's for, a
[`logs`](#logs) field with the entries themselves, and also `before` and
`after` fields which will either contain Unix millisecond timestamps or else be
null if no such limits were specified.
#### Example
```json
{
"initTurf": {
"turf": "localhost",
"since": null,
"before": null,
"logs": [
{
"id": "0782ebea-e8d3-4c6a-bf1c-5c336c82a0d3",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "blah blah",
"user": "foobar123",
"expire": 1679827515744,
"time": 1679826615744
},
"result": "yes"
},
{
"id": "4c54c5d9-6584-4d3b-ab62-e55f5f2033c4",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "foo bar baz",
"user": null,
"expire": 1679827571421,
"time": 1679826671421
},
"result": "no"
},
]
}
}
```
### `initShip`
This is sent as the inital update when you first subscribe to one of the
`/init/ship/...` paths. It's also returned by some of the scry paths. It
contains existing entries for a specific [`ship`](#ship), possibly limited to
entries before or after a specific timestamp.
It contains a [`ship`](#ship) field showing which ship it's for, a
[`logs`](#logs) field with the entries themselves, and also `before` and
`after` fields which will either contain Unix millisecond timestamps or else be
null if no such limits were specified.
#### Example
```json
{
"initShip": {
"ship": "zod",
"since": null,
"before": null,
"logs": [
{
"id": "0782ebea-e8d3-4c6a-bf1c-5c336c82a0d3",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "blah blah",
"user": "foobar123",
"expire": 1679827515744,
"time": 1679826615744
},
"result": "yes"
},
{
"id": "4c54c5d9-6584-4d3b-ab62-e55f5f2033c4",
"request": {
"code": 123456,
"turf": "localhost",
"ship": "zod",
"msg": "foo bar baz",
"user": null,
"expire": 1679827571421,
"time": 1679826671421
},
"result": "no"
},
]
}
}
```
---