summaryrefslogtreecommitdiff
path: root/doc/manual.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/manual.html')
-rw-r--r--doc/manual.html1337
1 files changed, 0 insertions, 1337 deletions
diff --git a/doc/manual.html b/doc/manual.html
deleted file mode 100644
index 20a6bc0..0000000
--- a/doc/manual.html
+++ /dev/null
@@ -1,1337 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:info="http://planete-kraus.eu/ns/info"
- xml:lang="en">
- <head>
- <link rel="stylesheet" type="text/css" href="style.css"/>
- <title>Webid-oidc manual</title>
- <info:subtitle>for version <info:version />,
- <info:updated /></info:subtitle>
- <info:copying>
- <p>
- This is the manual of webid-oidc (version <info:version />,
- <info:updated />), an implementation of the Solid
- authentication protocol for guile, client and server.
- </p>
- <p>Copyright <info:copyright-symbol /> 2020, 2021 Vivien
- Kraus</p>
- <info:quotation>
- <p>
- Permission is granted to copy, distribute and/or modify this
- document under the terms of the GNU Free Documentation
- License, Version 1.3 or any later version published by the
- Free Software Foundation; with no Invariant Sections, with no
- Front-Cover Texts, and with no Back-Cover Texts. A copy of the
- license is included in the section entitled ``GNU Free
- Documentation License''
- </p>
- </info:quotation>
- </info:copying>
- <info:author>
- <a href="mailto:vivien@planete-kraus.eu">Vivien Kraus</a>
- </info:author>
- <info:dircategory>
- Software libraries
- </info:dircategory>
- <info:direntry>
- <info:direntry-entry name="webid-oidc">
- Decentralized Authentication on the Web.
- </info:direntry-entry>
- </info:direntry>
- </head>
- <body>
- <h1>Decentralized Authentication on the Web</h1>
- <p>
- Authentication on the web is currently handled in the following
- way: anyone can install a server that will authenticate users on
- the web. The problem is interoperability. If a client (an
- application) wants to authenticate a user, it has to be approved
- by the authentication server. In other words, if
- <info:var>useful-program</info:var> wants to authenticate
- <info:var>MegaCorp</info:var> users, then
- <info:var>useful-program</info:var> has to register to
- <info:var>MegaCorp</info:var> first, and get approved. This goes
- against the principle of permission-less innovation, which is at
- the heart of the web.
- </p>
- <p>
- In the decentralized authentication web, the best attempt so far
- is that of ActivityPub. All servers are interoperable with
- respect to authentication: if user A emits an activity, it is
- forwarded by A's server to its recipients, and A's server is
- responsible for A's identity.
- </p>
- <p>
- The problem with that approach is that the data is tied to the
- application. It is not possible to use another application to
- process the data differently, or to use multiple data sources,
- in an interoperable way (without the ActivityPub server
- knowing). This means that on Activitypub, microblogging
- applications will not present different activities
- correctly. This also means that it is difficult to write a free
- replacement to a non-free application program, because it would
- need to manage the data.
- </p>
- <p>
- In the Solid ecosystem, there is a clear distinction between
- servers and applications. An application is free to read data
- from all places at the same time, using a permission-less
- authentication system. Since the applications do not need to
- store data, the cost of having users is neglectible, so users do
- not need prior approval before using them (making captchas and
- the like a thing of the past). Servers do not have a say in
- which applications the user uses.
- </p>
- <p>
- The authentication used is a slight modification of the
- well-established OpenID Connect. It is intended to work in a web
- browser, but this package demonstrates that it also works
- without a web browser.
- </p>
- <h1>The Json Web Token</h1>
- <p>
- The Json Web Token, or <info:dfn>JWT</info:dfn>, is a terse
- representation of a pair of JSON objects: the
- <info:dfn>header</info:dfn>, and the
- <info:dfn>payload</info:dfn>. The JWT can be
- <info:dfn>encoded</info:dfn> as a Json Web Signature
- (<info:dfn>JWS</info:dfn>), in which case the header is encoded
- to base64 with the URL alphabet, and without padding characters,
- the payload is also encoded to base64, and the concatenation of
- the encoding of the header, a dot, and the encoding of the
- payload is signed with some cryptography algorithm. In the
- following, we will only be interested by public-key
- cryptography. The concatenation of header, dot, payload, dot and
- signature in base64 is the encoding of the JWT.
- </p>
- <p>
- Decoded JWT are represented as a pair. The car of the pair is
- the header, and the cdr is the payload. Both the header and the
- payload use the JSON representation from srfi-180: objects are
- alists of <strong>symbols</strong> to values, arrays are
- vectors. It is unfortunate that guile-json has a slightly
- different representation, where alist keys are
- <emph>strings</emph>, but we hope that in the future SRFI-180
- will be more closely respected.
- </p>
- <h2>The ID token</h2>
- <p>
- The ID token is a special JWT that the application keeps for
- itself. It is signed by the identity provider, and contains the
- following claims:
- </p>
- <ul>
- <li><emph>webid</emph>, the URI of the user’s webid;</li>
- <li><emph>iss</emph>, the URI of the identity provider (issuer);</li>
- <li><emph>sub</emph>, the username (the webid-oidc issuer puts the webid again here, but it could be any string);</li>
- <li><emph>aud</emph>, the ID of the client application that is intended to receive the ID token;</li>
- <li><emph>nonce</emph>, some random data to change the signature;</li>
- <li><emph>exp</emph>, an UTC time (in seconds) for when the token expires;</li>
- <li><emph>iat</emph>, the time when it was issued.</li>
- </ul>
- <p>
- There are functions to work with ID tokens
- in <emph>(webid-oidc&#160;oidc-id-token)</emph>.
- </p>
- <info:deffn type="function" name="id-token?" arguments="object">
- <p>
- Check that <info:var>object</info:var> is a decoded ID token.
- </p>
- </info:deffn>
- <p>
- The following helper functions convert URIs to the URIs
- from <emph>(web&#160;uri)</emph> and times
- to <emph>(srfi&#160;srfi-19)</emph> dates.
- </p>
- <info:deffn type="function" name="id-token-webid" arguments="token">
- <info:deffnx type="function" name="id-token-iss" arguments="token" />
- <info:deffnx type="function" name="id-token-sub" arguments="token" />
- <info:deffnx type="function" name="id-token-aud" arguments="token" />
- <info:deffnx type="function" name="id-token-nonce" arguments="token" />
- <info:deffnx type="function" name="id-token-exp" arguments="token" />
- <info:deffnx type="function" name="id-token-iat" arguments="token" />
- <p>
- Get the suitable field from the payload
- of <info:var>token</info:var>.
- </p>
- </info:deffn>
- <p>
- ID tokens can be signed and encoded as a string, or decoded.
- </p>
- <info:deffn type="function" name="id-token-decode" arguments="token [#http-get]">
- <p>
- Decode <info:var>token</info:var>, as a string, into a decoded
- token. The signature verification will need to fetch the oidc
- configuration of the claimed issuer, and check the signature
- against the published keys. The <pre>http-get</pre> optional
- keyword argument can set a different implementation
- of <pre>http-get</pre>
- from <emph>(web&#160;client)</emph>. Return <pre>#f</pre> if
- it failed, or the decoded token otherwise.
- </p>
- </info:deffn>
- <info:deffn type="function" name="id-token-encode" arguments="token key">
- <p>
- Encode <info:var>token</info:var> and sign it with the
- issuer’s <info:var>key</info:var>.
- </p>
- </info:deffn>
- <info:deffn type="function" name="issue-id-token" arguments="issuer-key #alg #webid #iss #sub #aud #exp #iat">
- <p>
- Create an ID token, and encode it with
- <info:var>issuer-key</info:var>.
- </p>
- </info:deffn>
- <h2>The access token</h2>
- <p>
- The access token is obtained by the client through a token
- request, and is presented to the server on each authenticated
- request. It is signed by the identity provider, and it contains
- enough information so that the server knows who the user is and
- who the agent is, and most importantly the fingerprint of the
- key that the client should use in a DPoP proof.
- </p>
- <p>
- The API is defined in
- <emph>(webid-oidc&#160;access-token)</emph>.
- </p>
- <info:deffn type="function" name="access-token?" arguments="object">
- <p>
- Check that <info:var>object</info:var> is a decoded access token.
- </p>
- </info:deffn>
- <p>
- There are field getters for the access token:
- </p>
- <info:deffn type="function" name="access-token-webid" arguments="token">
- <info:deffnx type="function" name="access-token-iss" arguments="token" />
- <info:deffnx type="function" name="access-token-aud" arguments="token" />
- <info:deffnx type="function" name="access-token-exp" arguments="token" />
- <info:deffnx type="function" name="access-token-iat" arguments="token" />
- <info:deffnx type="function" name="access-token-cnf/jkt" arguments="token" />
- <info:deffnx type="function" name="access-token-client-id" arguments="token" />
- <p>
- Get the suitable field from the payload
- of <info:var>token</info:var>.
- </p>
- </info:deffn>
- <p>
- Access tokens can be signed and encoded as a string, or decoded.
- </p>
- <info:deffn type="function" name="access-token-decode" arguments="token [#http-get]">
- <p>
- Decode <info:var>token</info:var>, as a string, into a decoded
- token. As with the ID token, the signature verification will
- need to fetch the oidc configuration of the claimed issuer,
- and check the signature against the published keys. The
- <pre>http-get</pre> optional keyword argument can set a
- different implementation of <pre>http-get</pre> from
- <emph>(web&#160;client)</emph>, for instance to re-use the
- what has been obtained by the ID token validation. Return
- <pre>#f</pre> if it failed, or the decoded token otherwise.
- </p>
- </info:deffn>
- <info:deffn type="function" name="access-token-encode" arguments="token key">
- <p>
- Encode <info:var>token</info:var> and sign it with the
- issuer’s <info:var>key</info:var>.
- </p>
- </info:deffn>
- <info:deffn type="function" name="issue-access-token" arguments="issuer-key #alg #webid #iss #exp #iat [#client-key | #cnf/jkt] #client-id ">
- <p>
- Create an access token, and encode it with
- <info:var>issuer-key</info:var>. You can either set the
- <pre>#:cnf/jkt</pre> keyword argument with the fingerprint of
- the client key, or set <pre>#:client-key</pre> directly, in
- which case the fingerprint will be computed for you.
- </p>
- </info:deffn>
- <h2>The DPoP proof</h2>
- <p>
- This is a special JWT, that is signed by a key controlled by the
- application. The access token certifies that the key used to
- sign the proof is approved by the identity provider.
- </p>
- <info:deffn type="function" name="dpop-proof?" arguments="proof">
- <p>
- Check that the <info:var>proof</info:var> is a decoded DPoP
- proof. The validity of the proof is not checked by this
- function.
- </p>
- </info:deffn>
- <info:deffn type="function" name="dpop-proof-alg" arguments="proof">
- <info:deffnx type="function" name="dpop-proof-jwk" arguments="proof" />
- <info:deffnx type="function" name="dpop-proof-jti" arguments="proof" />
- <info:deffnx type="function" name="dpop-proof-htm" arguments="proof" />
- <info:deffnx type="function" name="dpop-proof-htu" arguments="proof" />
- <info:deffnx type="function" name="dpop-proof-iat" arguments="proof" />
- <p>
- Get the corresponding field of the proof.
- </p>
- </info:deffn>
- <info:deffn type="function" name="dpop-proof-decode" arguments="current-time jti-list method uri str cnf/check">
- <p>
- Check and decode a DPoP proof encoded
- as <info:var>str</info:var>.
- </p>
- <p>
- The <info:var>current-time</info:var> is passed as a date,
- time or number (of seconds).
- </p>
- <p>
- In order to prevent replay attacks, each proof has a unique
- random string that is remembered
- in <info:var>jti-list</info:var> until its expiration date is
- reached. See the <pre>make-jti-list</pre> function.
- </p>
- <p>
- The proof is limited to the scope of
- one <info:var>uri</info:var> and
- one <info:var>method</info:var>
- (<pre>'GET</pre>, <pre>'POST</pre> and so on).
- </p>
- <p>
- Finally, the key that is used to sign the proof should be
- confirmed by the identity provider. To this end,
- the <info:var>cnf/check</info:var> function is called with the
- fingerprint of the key. The function should check that the
- fingerprint is OK (return a boolean).
- </p>
- </info:deffn>
- <info:deffn type="function"
- name="make-jti-list"
- arguments="">
- <p>
- This function in <emph>(webid-oidc&#160;jti-list)</emph>
- creates an in-memory, async-safe, thread-safe cache for the
- proof IDs.
- </p>
- </info:deffn>
- <info:deffn type="function" name="dpop-proof-encode" arguments="proof key">
- <p>
- Encode the proof and sign it with <info:var>key</info:var>. To
- generate valid proofs, <info:var>key</info:var> should be the
- private key corresponding to the <pre>jwk</pre> field of the
- proof.
- </p>
- </info:deffn>
- <info:deffn type="function" name="issue-dpop-proof" arguments="client-key #alg #htm #htu #iat">
- <p>
- Create a proof, sign it and encode it with
- <info:var>client-key</info:var>. <info:var>client-key</info:var>
- should contain both the private and public key, because the
- public part is written in the proof and the private part is
- used to sign it.
- </p>
- </info:deffn>
- <h2>Generic JWTs</h2>
- <p>
- You can parse generic JWTs signed with JWS with the following
- functions from <emph>(webid-oidc&#160;jws)</emph>.
- </p>
- <info:deffn type="function" name="jws?" arguments="jwt">
- <p>
- Check that <info:var>jwt</info:var> is a decoded JWT signed
- with JWS.
- </p>
- </info:deffn>
- <info:deffn type="function" name="jws-alg" arguments="jwt">
- <p>
- Get the algorithm used to sign <info:var>jwt</info:var>.
- </p>
- </info:deffn>
- <info:deffn type="function" name="jws-decode" arguments="str lookup-keys">
- <p>
- Check and decode a JWT signed with JWS and encoded
- as <info:var>str</info:var>.
- </p>
- <p>
- Since the decoding and signature verification happen at the
- same time (for user friendliness), the
- <info:var>lookup-keys</info:var> function is used. It is
- passed as arguments the decoded JWT (but the signature is not
- checked yet), and it should return a public key, a public key
- set or a list of public keys. If the key lookup failed, this
- function should raise an exception.
- </p>
- </info:deffn>
- <info:deffn type="function" name="jws-encode" arguments="jwt key">
- <p>
- Encode the JWT and sign it with <info:var>key</info:var>.
- </p>
- </info:deffn>
- <h1>Caching on server side</h1>
- <p>
- Both the identity provider and the resource server need to cache
- things. The identity provider will cache application webids, and
- the resource server will cache the identity provider keys, for
- instance.
- </p>
- <p>
- The solution is to use a file-system cache. Every response
- (except those that have a cache-control policy of no-store) are
- stored to a sub-directory of <emph>XDG_CACHE_HOME</emph>. Each
- store has a 5% chance of triggering a cleanup of the cache. When
- a cleanup occurs, each cached response has a 5% chance of being
- dropped, including responses that are indicated as valid. This
- way, a malicious cache response that has a maliciously long
- validity will not stay too long in the cache. A log line will
- indicate which items are dropped.
- </p>
- <p>
- The <emph>(webid-oidc&#160;cache)</emph> module exports two
- functions to deal with the cache.
- </p>
- <info:deffn type="function" name="clean-cache" arguments="[#percents] [#dir]">
- <p>
- Drop <info:var>percents</info:var>% of the cache right now, in
- <info:var>dir</info:var> (defaults to some place within
- <emph>XDG_CACHE_HOME</emph>).
- </p>
- </info:deffn>
- <info:deffn type="function" name="with-cache" arguments="[#current-time] [#http-get] [#dir]">
- <p>
- Return a function acting as <emph>http-get</emph> from
- <emph>(web&#160;client)</emph> (takes an URI as the first
- parameter, and an optional <info:var>#:headers</info:var> set,
- and returns 2 values, the response and its body).
- </p>
- <p>
- The cache will be read and written in <info:var>dir</info:var>
- (defaults to some place within <emph>XDG_CACHE_HOME</emph>),
- and the <info:var>current-time</info:var> number of seconds,
- SRFI-19 time or date, or time-returning thunk will be used to
- check for the validity of responses.
- </p>
- <p>
- The back-end function, <info:var>http-get</info:var>, defaults
- to that of <emph>(web&#160;client)</emph>.
- </p>
- </info:deffn>
- <h1>What if something goes wrong?</h1>
- <p>
- The library will raise an exception whenever something fishy
- occurs. For instance, if a signature is invalid, or the
- expiration date has passed. All exception types are defined in
- <emph>(webid-oidc errors)</emph>.
- </p>
- <info:deffn type="function" name="error->str" arguments="error [#depth]">
- <p>
- Return a string explaining the <info:var>error</info:var>. You
- can limit the <info:var>depth</info:var> of the explanation as
- an integer.
- </p>
- </info:deffn>
- <info:deftp type="exception type" name="&amp;not-base64" arguments="value cause">
- <p>
- This exception is raised when the base64 decoding function
- failed. <info:var>value</info:var> is the incorrect input,
- and <info:var>cause</info:var> is a low-level error.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-json" arguments="value cause">
- <p>
- Cannot decode <info:var>value</info:var> to a JSON object.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-turtle" arguments="value cause">
- <p>
- Cannot decode <info:var>value</info:var> to a RDF graph.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unsupported-crv" arguments="crv">
- <p>
- The identifier <info:var>crv</info:var> does not identify an
- elliptic curve.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-jwk" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a JWK.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-public-jwk" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a public JWK.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-private-jwk" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a private JWK.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-jwks" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a set of public keys.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unsupported-alg" arguments="value">
- <p>
- <info:var>value</info:var> does not identify a valid hash algorithm.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;invalid-signature" arguments="key payload signature">
- <p>
- <info:var>key</info:var> has not signed
- <info:var>payload</info:var> with
- <info:var>signature</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;missing-alist-key" arguments="value key">
- <p>
- <info:var>value</info:var> isn’t an alist, or is missing a
- value with <info:var>key</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-jws-header" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a decoded JWS header.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-jws-payload" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a decoded JWS payload.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-jws" arguments="value cause">
- <p>
- <info:var>value</info:var> does not identify a decoded JWS.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-in-3-parts" arguments="string separator">
- <p>
- <info:var>string</info:var> cannot be split into 3 parts with
- <info:var>separator</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;no-matching-key" arguments="candidates alg payload signature">
- <p>
- No key among <info:var>candidates</info:var> could verify
- <info:var>signature</info:var> signed with
- <info:var>alg</info:var> for <info:var>payload</info:var>,
- because the signature mismatched for all keys.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-decode-jws" arguments="value cause">
- <p>
- The <info:var>value</info:var> string is not an encoding of a valid JWS.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-encode-jws" arguments="jws key cause">
- <p>
- The <info:var>jws</info:var> cannot be signed.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;request-failed-unexpectedly" arguments="response-code response-reason-phrase">
- <p>
- We expected the request to succeed, but the server sent a
- non-OK <info:var>response-code</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unexpected-header-value" arguments="header value">
- <p>
- We did not expect the server to respond with
- <info:var>header</info:var> set to <info:var>value</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unexpected-response" arguments="response cause">
- <p>
- The <info:var>response</info:var> (from
- <emph>(web response)</emph>) is not appropriate.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-oidc-configuration" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an OIDC configuration.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-webid-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the webid field in the JWT
- is missing (if <pre>#f</pre>), or not an acceptable value.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-sub-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the sub field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-iss-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the iss field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-aud-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the aud field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-iat-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the iat field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-exp-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the exp field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-cnf/jkt-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the cnf/jkt field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-client-id-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the client-id field is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-redirect-uris-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the redirect-uris field of a
- client manifest is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-typ-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the typ field in the DPoP proof
- header is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-jwk-field" arguments="value cause">
- <p>
- The <info:var>value</info:var> of the jwk field in the DPoP
- proof header is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-jti-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the jti field in the DPoP
- proof is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-nonce-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the nonce field in the DPoP
- proof is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-htm-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the htm field in the DPoP
- proof is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;incorrect-htu-field" arguments="value">
- <p>
- The <info:var>value</info:var> of the htu field in the DPoP
- proof is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-access-token" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an access token.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-access-token-header" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an access token header.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-access-token-payload" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an access token payload.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-fetch-issuer-configuration" arguments="issuer cause">
- <p>
- It is impossible to fetch the configuration of
- <info:var>issuer</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-fetch-jwks" arguments="issuer uri cause">
- <p>
- It is impossible to fetch the keys of
- <info:var>issuer</info:var> at <info:var>uri</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-decode-access-token" arguments="value cause">
- <p>
- The <info:var>value</info:var> string is not an encoding of a
- valid access token.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-encode-access-token" arguments="access-token key cause">
- <p>
- The <info:var>access-token</info:var> cannot be signed.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-dpop-proof" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not a DPoP proof.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-dpop-proof-header" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not a DPoP proof header.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-dpop-proof-payload" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not a DPoP proof payload.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;dpop-method-mismatch" arguments="signed requested">
- <p>
- The method value <info:var>signed</info:var> in the DPoP proof
- does not match the method that is
- <info:var>requested</info:var> on the server.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;dpop-uri-mismatch" arguments="signed requested">
- <p>
- The URI value <info:var>signed</info:var> in the DPoP proof
- does not match the URI that is <info:var>requested</info:var>
- on the server.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;dpop-signed-in-future" arguments="signed current">
- <p>
- The proof is <info:var>signed</info:var> for a date which is
- too much ahead of the <info:var>current</info:var> time.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;dpop-too-old" arguments="signed current">
- <p>
- The proof was <info:var>signed</info:var> at a past date of
- <info:var>current</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;dpop-unconfirmed-key" arguments="key expected cause">
- <p>
- The confirmation of <info:var>key</info:var> is not what is
- <info:var>expected</info:var>, or (if a function was passed as
- <info:var>cnf/check</info:var>) the <info:var>cause</info:var>
- exception occurred while confirming.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;jti-found" arguments="jti cause">
- <p>
- The <info:var>jti</info:var> of the proof has already been
- issued in a recent past.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-decode-dpop-proof" arguments="value cause">
- <p>
- The <info:var>value</info:var> string is not an encoding of a
- valid DPoP proof.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-encode-dpop-proof" arguments="dpop-proof key cause">
- <p>
- The <info:var>dpop-proof</info:var> cannot be signed.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-fetch-linked-data" arguments="uri cause">
- <p>
- Could not fetch the graph referenced by
- <info:var>uri</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-a-client-manifest" arguments="value cause">
- <p>
- The <info:var>client-manifest</info:var> is incorrect.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unauthorized-redirection-uri" arguments="manifest uri">
- <p>
- The authorization <info:var>uri</info:var> is not advertised
- in <info:var>manifest</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-serve-public-manifest" arguments="">
- <p>
- You cannot serve the public client manifest.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;no-client-manifest-registration" arguments="id">
- <p>
- The <info:var>id</info:var> client manifest does not have a
- registration triple in its document.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;inconsistent-client-manifest-id" arguments="id advertised-id">
- <p>
- The client <info:var>manifest</info:var> is being fetched at
- <info:var>id</info:var>, but it is valid for another client
- <info:var>advertised-id</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-fetch-client-manifest" arguments="id cause">
- <p>
- Could not fetch a client manifest at <info:var>id</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-authorization-code" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an authorization code.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-authorization-code-header" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an authorization code header.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-authorization-code-payload" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an authorization code payload.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;authorization-code-expired" arguments="exp current-time">
- <p>
- The authorization code has expired at
- <info:var>exp</info:var>, it is now
- <info:var>current-time</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-decode-authorization-code" arguments="value cause">
- <p>
- The <info:var>value</info:var> string is not an encoding of a
- valid authorization code.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-encode-authorization-code" arguments="authorization-code key cause">
- <p>
- The <info:var>authorization-code</info:var> cannot be signed.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;invalid-refresh-token" arguments="refresh-token">
- <p>
- The <info:var>refresh-token</info:var> is unknown to the
- identity provider.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;invalid-key-for-refresh-token" arguments="key jkt">
- <p>
- The refresh token was issued for <info:var>jkt</info:var>, but
- it is used with <info:var>key</info:var>.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-id-token" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an ID token.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-id-token-header" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an ID token header.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;not-an-id-token-payload" arguments="value cause">
- <p>
- The <info:var>value</info:var> is not an ID token payload.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-decode-id-token" arguments="value cause">
- <p>
- The <info:var>value</info:var> string is not an encoding of a
- valid ID token.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;cannot-encode-id-token" arguments="id-token key cause">
- <p>
- The <info:var>id-token</info:var> cannot be signed.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unknown-client-locale" arguments="web-locale c-locale">
- <p>
- The <info:var>web-locale</info:var> of the client, translated
- to C as <info:var>c-locale</info:var>, cannot be set. This
- exception is always continuable; if the handler returns, then
- the page will be served in the english locale.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unsupported-grant-type" arguments="value">
- <p>
- The token request failed to indicate a
- <info:var>value</info:var> for the grant type, or indicated an
- unsupported grant type.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;no-authorization-code" arguments="">
- <p>
- The token request forgot to put an authorization code.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;no-refresh-token" arguments="">
- <p>
- The token request forgot to put a refresh token with the
- request.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;unconfirmed-provider" arguments="subject provider">
- <p>
- <info:var>provider</info:var> is not confirmed by
- <info:var>subject</info:var> as an identity provider.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;no-provider-candidates" arguments="webid causes">
- <p>
- The <info:var>webid</info:var> cannot be certified by any
- identity providers. The <info:var>causes</info:var> alist
- indicates an error for each candidates.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;neither-identity-provider-nor-webid" arguments="uri why-not-identity-provider why-not-webid">
- <p>
- The <info:var>uri</info:var> you passed to get an
- authorization code is neither an identity provider (because
- <info:var>why-not-identity-provider</info:var>) nor a webid
- (because <info:var>why-not-webid</info:var>).
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;token-request-failed" arguments="cause">
- <p>
- The token request failed on the server.
- </p>
- </info:deftp>
- <info:deftp type="exception type" name="&amp;profile-not-found" arguments="webid iss dir">
- <p>
- The <info:var>webid</info:var>, as certified by
- <info:var>iss</info:var>, cannot be refreshed because we don’t
- have a refresh token stored in <info:var>dir</info:var>.
- </p>
- </info:deftp>
-
- <h1>Running an Identity Provider</h1>
- <p>
- This project is packaged with a barebones identity provider. It
- has an authorization endpoint and a token endpoint (and it
- serves its public keys), but it is only intended for one
- specific person.
- </p>
- <p>
- You can start it by invoking the <pre>webid-oidc-issuer</pre>
- program, with the following options:
- </p>
- <ul>
- <li>
- <pre>-h</pre>, or <pre>--help</pre> prints a summary of
- options and exit.
- </li>
- <li>
- <pre>-v</pre>, or <pre>--version</pre> prints the version of
- the program and exits.
- </li>
- <li>
- <pre>-i <info:var>URI</info:var></pre>, or
- <pre>--issuer=<info:var>URI</info:var></pre> sets the global
- server name of the identity provider. It should have an empty
- path.
- </li>
- <li>
- <pre>-k <info:var>FILE.jwk</info:var></pre>, or
- <pre>--key-file=<info:var>FILE.jwk</info:var></pre> sets the
- file name where to read or generate a key for the identity
- provider. This file should be JSON, containing the
- representation of a JWK key pair.
- </li>
- <li>
- <pre>-s <info:var>WEBID</info:var></pre>, or
- <pre>--subject=<info:var>WEBID</info:var></pre> sets the webid
- of the only user of the identity provider. This is an URI,
- pointing to a RDF node corresponding to the user’s profile.
- </li>
- <li>
- <pre>-w <info:var>PASSWORD</info:var></pre>, or
- <pre>--password=<info:var>PASSWORD</info:var></pre>, sets the
- password that the user must enter to authorize an
- application.
- </li>
- <li>
- <pre>-j <info:var>URI</info:var></pre>, or
- <pre>--jwks-uri=<info:var>URI</info:var></pre> tells the
- server that requests to <info:var>URI</info:var> should be
- responded with the public key used to sign the tokens.
- </li>
- <li>
- <pre>-a <info:var>URI</info:var></pre>, or
- <pre>--authorization-endpoint-uri=<info:var>URI</info:var></pre>
- tells the server that requests to <info:var>URI</info:var>
- should be treated as authorization requests.
- </li>
- <li>
- <pre>-t <info:var>URI</info:var></pre>, or
- <pre>--token-endpoint-uri=<info:var>URI</info:var></pre> tells
- the server that requests to <info:var>URI</info:var> should be
- treated as token negociation requests.
- </li>
- <li>
- <pre>-p <info:var>PORT</info:var></pre>, or
- <pre>--port=<info:var>PORT</info:var></pre>, change the port
- number used by the server. By default, it is set to 8080.
- </li>
- <li>
- <pre>-l <info:var>FILE.log</info:var></pre>, or
- <pre>--log-file=<info:var>FILE.log</info:var></pre> let the
- server dump all its output to
- <info:var>FILE.log</info:var>. Since I don’t know how to deal
- with syslog, this is the only way to keep logs with a shepherd
- service.
- </li>
- <li>
- <pre>-e <info:var>FILE.err</info:var></pre>, or
- <pre>--error-file=<info:var>FILE.err</info:var></pre> let the
- server dump all its errors to <info:var>FILE.err</info:var>.
- </li>
- </ul>
- <p>
- The program is sensitive to the environment variables. The most
- important one is <emph>LANG</emph>, which influences how the
- program is internationalized to the server administrator (the
- pages served to the user use the user agent’s locale). This
- changes the long form of the options, and the language in the
- log files.
- </p>
- <p>
- The <emph>XDG_DATA_HOME</emph> should point to some place where
- the program will store refresh tokens, under the
- <pre>webid-oidc</pre> directory. For a system service, you might
- want to define that environment to <pre>/var/lib</pre>, for
- instance.
- </p>
- <p>
- The <emph>XDG_CACHE_HOME</emph> should point to a directory
- where to store the seed of the random number generator (under a
- <pre>webid-oidc</pre> directory, again). Changing the seed only
- happens when a program starts to require the random number
- generator. You can safely delete this directory, but you need to
- restart the program to actually change the seed.
- </p>
- <h1>Running a Resource Server</h1>
- <p>
- A Solid server is the server that manages your data. It needs to
- check that the proofs of possession are correct, and the
- possessed key is signed by the identity provider.
- </p>
- <h2>Running webid-oidc-reverse-proxy</h2>
- <p>
- The distribution comes with a reverse proxy, aptly named
- <pre>webid-oidc-reverse-proxy</pre>, to listen to an interface,
- take requests, authenticate them, and pass them to a backend
- with an additional header containing the webid of the agent, if
- authenticated.
- </p>
- <p>The reverse proxy is invoked with the following arguments:</p>
- <ul>
- <li>
- <pre>-p</pre> <info:var>PORT</info:var>,
- <pre>--port=</pre><info:var>PORT</info:var>: the port on which
- the reverse proxy listens;
- </li>
- <li>
- <pre>-i</pre> <info:var>INBOUND</info:var>,
- <pre>--inbound-uri=</pre><info:var>INBOUND</info:var>: the
- public name of the server;
- </li>
- <li>
- <pre>-o</pre> <info:var>OUTBOUND</info:var>,
- <pre>--outbound-uri=</pre><info:var>OUTBOUND</info:var>: the
- address of the backend;
- </li>
- <li>
- <pre>-H</pre> <info:var>HEADER</info:var>,
- <pre>--header=</pre><info:var>HEADER</info:var>: replace the
- name of the header that will contain the webid of the
- user. Defaults to <pre>XXX-Agent</pre>. Please note that this
- value should be ASCII, otherwise it’s not guaranteed that the
- reverse proxy will drop other capitalizations of the header in
- malicious requests.
- </li>
- <li>
- <pre>-l <info:var>FILE.log</info:var></pre>, or
- <pre>--log-file=<info:var>FILE.log</info:var></pre> let the
- server dump all its output to
- <info:var>FILE.log</info:var>. See the identity provider
- comment.
- </li>
- <li>
- <pre>-e <info:var>FILE.err</info:var></pre>, or
- <pre>--error-file=<info:var>FILE.err</info:var></pre> let the
- server dump all its errors to <info:var>FILE.err</info:var>.
- </li>
- </ul>
- <p>
- You can localize the interface by setting the
- <info:var>LANG</info:var> environment variable.
- </p>
- <h2>The authenticator</h2>
- <p>
- In <emph>(webid-oidc&#160;jws)</emph>, the following function
- gives a simple API for a web server:
- </p>
- <info:deffn type="function"
- name="make-authenticator"
- arguments="jti-list [#server-uri] [#current-time] [#http-get]">
- <p>
- Create an authenticator, i.e. a function that takes a request
- and request body and returns the webid of the authenticated
- user, or <pre>#f</pre> if it is not authenticated.
- </p>
- <p>
- To prevent replay attacks, each request is signed by the
- client with a different unique padding value. If such a value
- has already been seen, then the request must fail.
- </p>
- <p>
- The authenticator expects the client to demonstrate the
- possession of a key that the identity provider knows. So the
- client creates a DPoP proof, targetted to a specific URI. In
- order to check that the URI is correct, the authenticator
- needs the public URI of the service.
- </p>
- <p>
- The JTIs are checked within a small time frame. By default,
- the system time will be used. Otherwise, you can customize the
- <pre>current-time</pre> optional keyword argument, to pass a
- thunk returning a time from <emph>(srfi srfi-19)</emph>.
- </p>
- <p>
- You may want to customize the <info:var>http-get</info:var>
- optional keyword argument to pass a function to replace
- <pre>http-get</pre> from <emph>(http client)</emph>. This
- function takes an URI and optional <pre>#:headers</pre>
- arguments, makes the request, and return two values: the
- response, and the response body.
- </p>
- <p>
- This function, in
- <emph>(webid-oidc&#160;resource-server)</emph>, returns a web
- request handler, taking the request and request body, and
- returning the subject of the access token. If an error
- happens, it is thrown; the function always returns a valid
- URI.
- </p>
- </info:deffn>
-
- <h1>Running a client</h1>
- <p>
- To run a client, you need to proceed in two steps. First,
- acquire an OIDC ID token and an access token from the identity
- provider, and then present the access token and a proof of
- possession of the linked key in each request, in a DPoP HTTP
- header.
- </p>
- <p>
- The first operation is performed by the
- <emph>(webid-oidc&#160;client)</emph> module.
- </p>
- <info:deffn type="function" name="authorize" arguments="host/webid #client-id #redirect-uri [#state] [#http-get]">
- <p>
- The user enters a valid webid or a host name, and then this
- function will query it (with the <info:var>http-get</info:var>
- parameter, by default the web client from
- <emph>(web&#160;client)</emph>) to determine the authorization
- endpoint. The function will return an alist of authorization
- URIs, indexed by approved identity provider URIs, that the
- user should browse with a traditional web browser.
- </p>
- <p>
- Each application should have its own webid, or in that case
- <info:var>client-id</info:var>, that can be dereferenced by
- the identity provider.
- </p>
- <p>
- Once the user has given authorization, the user’s agent will
- be redirected to <info:var>redirect-uri</info:var>, with the
- authorization code as a GET parameter. It is possible to pass
- a <info:var>state</info:var>, but this is optional.
- </p>
- </info:deffn>
- <p>
- Once the client gets the authorization code, it is necessary to
- create an access token and ID token.
- </p>
- <info:deffn type="function" name="token" arguments="host client-key [#authorization-code] [#refresh-token] [#http-get] [#http-post] [#current-time]">
- <p>
- Trade an <info:var>authorization-code</info:var>, or a
- <info:var>refresh-token</info:var>, for an ID token and an
- access token bound to the <info:var>client-key</info:var>
- issued by <info:var>host</info:var>, the identity provider.
- </p>
- <p>
- You can override the HTTP client used
- (<info:var>http-get</info:var> and
- <info:var>http-post</info:var>), and how to compute the time
- (<info:var>current-time</info:var>).
- </p>
- </info:deffn>
- <p>
- In an application, you would have a list of profiles in
- XDG_DATA_HOME, consisting of triples (webid, issuer, refresh
- token).
- </p>
- <info:deffn type="function" name="list-profiles" arguments="[#dir]">
- <p>
- Read the list of available profiles. Returns a list of
- triples, webid, issuer, reresh token.
- </p>
- <p>
- By default, this function will look for the profiles file in
- XDG_DATA_HOME. You can bypass it by providing the
- <info:var>#dir</info:var> optional keyword argument.
- </p>
- </info:deffn>
- <info:deffn type="function" name="setup" arguments="get-host/webid choose-provider browse-authorization-uri #client-id #redirect-uri [#dir] [#http-get] [#http-post] [#current-time]">
- <p>
- Negociate a refresh token, and save it. The function returns 3
- values: the decoded ID token pyload, the encoded access token
- and the key pair.
- </p>
- <p>
- The <info:var>get-host/webid</info:var> thunk should ask the
- user’s webid or identity provider, and return
- it. <info:var>choose-provider</info:var> is called with a list
- of possible identity providers as host names (strings), and
- the user should choose one. The chosen one is
- returned. Finally,
- <info:var>browse-authorization-uri</info:var> should ask or
- let the user browse an URI as its argument, and return the
- authorization code taken from the redirect URI.
- </p>
- <p>
- The refresh token is saved to disk, as a profile, in
- XDG_DATA_HOME. Pass the optional <info:var>#dir</info:var>
- keyword argument to override the location.
- </p>
- <p>
- You need to set <info:var>client-id</info:var> to the public
- webid of the app, and <info:var>redirect-uri</info:var> to one
- of the approved redirection URIs for the application ID.
- </p>
- </info:deffn>
- <info:deffn type="function" name="login" arguments="webid issuer refresh-token key [#dir] [#http-get] [#http-post] [#current-time]">
- <p>
- If you have already a known profile, you can use it to
- automatically log in. This function might update the refresh
- token if it changed, so you can again set
- <info:var>#dir</info:var>. Please note that the
- <info:var>refresh-token</info:var> is bound to the client
- <info:var>key</info:var> on server side, so you must always
- use the same <info:var>key</info:var>.
- </p>
- </info:deffn>
- <info:deffn type="function" name="refresh" arguments="id-token key [#dir] [#http-get] [#http-post] [#current-time]">
- <p>
- If you have an ID token bound to a known profile, this helper
- function will look up the associated refresh token and log in.
- </p>
- </info:deffn>
- <info:deffn type="function" name="make-client" arguments="id-token access-token key [#dir] [#http-get] [#http-post] [#http-request] [#current-time]">
- <p>
- Return a replacement of <pre>http-request</pre> from
- <emph>(web&#160;client)</emph>, that automatically signs
- requests and refresh the tokens when needed.
- </p>
- <p>
- <info:var>#http-get</info:var> and
- <info:var>#http-post</info:var> are only used to refresh the
- tokens, while <info:var>#http-request</info:var> is used as a
- back-end for the requests.
- </p>
- <p>
- <info:var>#current-time</info:var> is set to a thunk that
- returns the time. It is used to issue DPoP proofs.
- </p>
- </info:deffn>
- <p>
- An example application is provided as the
- <pre>webid-oidc-example-app</pre> program. It demonstrates how
- authentication is done. It should help you understand how
- webid-oidc works.
- </p>
- <p>
- The identity provider needs to call the application on the
- web. So, your client should have a public endpoint on the web.
- </p>
- <info:deffn type="function" name="serve-application" arguments="id redirect-uri [#client-name] [#client-uri]">
- <p>
- Return a handler for web requests to serve the application
- manifest and the redirection to transmit the authorization
- code. You should set the <info:var>client-name</info:var> to
- your application name and <info:var>client-uri</info:var> to
- point to where to a presentation of your application.
- </p>
- </info:deffn>
- <p>
- The <pre>webid-oidc-client-service</pre> program can run a
- server to serve these resources. It is invoked with the
- following options:
- </p>
- <ul>
- <li>
- <pre>-h</pre>, or <pre>--help</pre> prints a summary of the
- options and exit.
- </li>
- <li>
- <pre>-v</pre>, or <pre>--version</pre> prints the version of
- the program and exits.
- </li>
- <li>
- <pre>-i <info:var>URI</info:var></pre>, or
- <pre>--client-id=<info:var>URI</info:var></pre> sets the
- global identitifier of the application, which is dereferenced
- to a semantic resource.
- </li>
- <li>
- <pre>-r <info:var>URI</info:var></pre>, or
- <pre>--redirect-uri=<info:var>URI</info:var></pre> sets the
- redirection URI.
- </li>
- <li>
- <pre>-n <info:var>NAME</info:var></pre>, or
- <pre>--client-name=<info:var>NAME</info:var></pre> sets the
- name of your application, so that it is shown when the user
- gets an authorization. The webid-oidc issuer program that
- comes with this package does not display it, because it could
- be dishonest, but other implementations might.
- </li>
- <li>
- <pre>-u <info:var>URI</info:var></pre>, or
- <pre>--client-uri=<info:var>URI</info:var></pre>, sets an URI
- for the identity provider to learn more about your app.
- </li>
- <li>
- <pre>-p <info:var>PORT</info:var></pre>, or
- <pre>--port=<info:var>PORT</info:var></pre>, change the port
- number used by the server. By default, it is set to 8080.
- </li>
- <li>
- <pre>-l <info:var>FILE.log</info:var></pre>, or
- <pre>--log-file=<info:var>FILE.log</info:var></pre> let the
- server dump all its output to <info:var>FILE.log</info:var>.
- </li>
- <li>
- <pre>-e <info:var>FILE.err</info:var></pre>, or
- <pre>--error-file=<info:var>FILE.err</info:var></pre> let the
- server dump all its errors to <info:var>FILE.err</info:var>.
- </li>
- </ul>
- <p>
- The program is sensitive to the environment variable
- <emph>LANG</emph>, which influences how the program is
- internationalized to the server administrator. This changes the
- long form of the options, and the language in the log files.
- </p>
-
- <h1 type="appendix">GNU Free Documentation License</h1>
- <info:gfdl />
-
- <h1 type="unnumbered">Index</h1>
- <info:printindex />
- </body>
-</html>
-
-<!-- Local Variables: -->
-<!-- mode: nxml -->
-<!-- End: -->