aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-09-06 18:09:32 +0200
committerFlorian Dold <florian@dold.me>2023-09-06 18:09:32 +0200
commit6d7d5d19fd35a50ac38f3febd945a0b97fb0ac01 (patch)
tree9ab539ae10fc1be78433e47505f9d860bdfa89e1
parent1a2f2c9600917992db2bbe4eed5fef00f40d895b (diff)
downloaddocs-6d7d5d19fd35a50ac38f3febd945a0b97fb0ac01.tar.gz
docs-6d7d5d19fd35a50ac38f3febd945a0b97fb0ac01.tar.bz2
docs-6d7d5d19fd35a50ac38f3febd945a0b97fb0ac01.zip
draft DD49, address libeufin-bank API FIXMEs
-rw-r--r--core/api-libeufin-bank.rst136
-rw-r--r--design-documents/049-auth.rst177
-rw-r--r--design-documents/index.rst1
3 files changed, 233 insertions, 81 deletions
diff --git a/core/api-libeufin-bank.rst b/core/api-libeufin-bank.rst
index f7b1a7e9..4e6296bf 100644
--- a/core/api-libeufin-bank.rst
+++ b/core/api-libeufin-bank.rst
@@ -22,29 +22,6 @@
Libeufin Bank API
=================
-.. note::
-
- **FIXMEs:**
-
- * Clarify where the libeufin-bank API provides the Taler Wire Gateway API
- and Bank Integration API
-
- * /config => { type: "libeufin-bank" }
- * /bank-integration-api/config => { type: "taler-bank-integration" }
- * /accounts/$USERNAME/taler-wire-gateway-api/config => { type: "taler-wire-gateway" }
- * only for accounts that have been configured as a Taler exchange account
- * /accounts/$USERNAME/taler-revenue-api/config { type: "taler-revenue-api" }
-
- * we used to call this the anastasis facade
-
- * have flag for exchange account to enable bouncing transactions that don't have a reserve pub
- or above a certain threshold
- * in (all?) accounts, we can manage an access token for read-only access
- * for public accounts, the read-only access token could simply be empty or a well-known token
- * path: ``/accounts/${username}/taler-wire-gateway-api``?
-
- * The pagination of account transactions right now is page-based, do we want that?
-
.. contents:: Table of Contents
Introduction
@@ -58,7 +35,7 @@ Authentication
Some requests require the client to authenticate via HTTP Basic auth (RFC 7617)
or using a bearer token which can be obtained or refreshed from the
-``/accounts/$USERNAME/login`` endpoint.
+``/accounts/$USERNAME/auth-token`` endpoint.
When using Basic authentication, the user-id must be the libeufin-bank
username, and the password the password for the corresponding user.
@@ -69,44 +46,9 @@ the taler-wire-gateway facade via such a manually configured access token.
The ``admin`` user is a special, hard-coded username. Some requests require the
client to authenticate as the admin.
-.. http:post:: /accounts/$USERNAME/login
-
- **Parameters**
-
- .. ts:def:: LoginRequest
-
- interface LoginRequest {
- scope: "readonly" | "write";
-
- // Server may impose its own upper bound
- // on the token validity duration
- duration?: RelativeTime;
-
- // Can this token be refreshed?
- // Defaults to false.
- refreshable?: boolean;
- }
-
- **Response:**
-
- TBD.
-
- **Details:**
-
- .. note::
+.. http:post:: /accounts/$USERNAME/auth-token
- Typically the ``access_token`` would be an EdDSA signature
- over (username, scope, timestamp, expiry).
-
- Alternatively, valid access tokens could also be random identifiers
- stored in a database table.
-
- .. ts:def:: LoginSuccessResponse
-
- interface LoginSuccessResponse {
- expiration: Timestamp;
- access_token: string;
- }
+ See :ref:`DD 48 token endpoint <dd48-token>`.
Libeufin Bank Web UI
@@ -168,7 +110,16 @@ Account Management
// Legal name of the account owner
name: string;
- is_public: boolean;
+ // Defaults to false.
+ is_public?: boolean;
+
+ // Is this a taler exchange account?
+ // If true:
+ // - incoming transactions to the account that do not
+ // have a valid reserve public key are automatically
+ // - the account provides the taler-wire-gateway-api endpoints
+ // Defaults to false.
+ is_taler_exchange?: boolean;
// Addresses where to send the TAN for transactions.
// Currently only used for cashouts.
@@ -266,6 +217,10 @@ Account Management
// Legal name associated with $username.
// When missing, the old name is kept.
name?: string;
+
+ // If present, change the is_exchange configuration.
+ // See `RegisterAccountRequest`
+ is_exchange?: boolean;
}
**Response:**
@@ -442,23 +397,30 @@ Transactions
Retrieve a subset of transactions related to $account_name. Without
query parameters, it returns the last 5 transactions.
- **Request**
+ The list of returned transactions is determined by a row ID *starting point*
+ and a signed non-zero integer *delta*:
- .. note::
+ * If *delta* is positive, return a list of up to *delta* transactions (all matching
+ the filter criteria) strictly **after** the starting point. The transactions are sorted
+ in **ascending** order of the row ID.
+ * If *delta* is negative, return a list of up to *-delta* transactions (all matching
+ the filter criteria) strictly **before** the starting point. The transactions are sorted
+ in **descending** order of the row ID.
- We should migrate this to use the same kind of pagination interface
- that we use elsewhere in Taler (start and +/- delta).
+ If *starting point* is not explicitly given, it defaults to:
+
+ * A value that is **smaller** than all other row IDs if *delta* is **positive**.
+ * A value that is **larger** than all other row IDs if *delta* is **negative**.
+
+ **Request**
:query long_poll_ms: Optional number to express how many milliseconds the server
should wait for at least one result to be shown. If not given, the server
responds immediately, regardless of the result.
- :query page: page number starting from 1. Page 1 has the latest transactions
- and 1 is the default value.
- :query size: how many transactions per page. It must be at least 1 and defaults to 5.
- :query from_ms: Optional. Filters the results to transactions *from* (inclusively) this
- timestamp in milliseconds
- :query until_ms: Optional. Filters the results to transactions *until* (inclusively) this
- timestamp in milliseconds
+ :query start: *Optional.*
+ Row identifier to explicitly set the *starting point* of the query.
+ :query delta:
+ The *delta* value that determines the range of the query.
**Response**
@@ -488,7 +450,7 @@ Transactions
// Transaction unique ID. Matches
// $transaction_id from the URI.
- uid: string;
+ row_id: number;
date: Timestamp;
}
@@ -928,17 +890,29 @@ Cashouts
Taler Bank Integration API
--------------------------
-Every endpoint is served under ``/integration-api``.
-See :doc:`/core/api-bank-integration`. This API handles the communication
-with Taler wallets.
+.. http:any:: /taler-integration/*
+
+ All endpoints under this prefix are specified by the.
+ :doc:`GNU Taler bank integration API </core/api-bank-integration>`.
+ This API handles the communication with Taler wallets.
Taler Wire Gateway API
----------------------
-Served under ``/taler-wire-gateway``. Currently,
-only the :ref:`admin/add-incoming <twg-admin-add-incoming>` endpoint
-is implemented. This endpoint allows testing, but the rest of
-this API does never involve the Sandbox.
+.. http:any:: /accounts/$USERNAME/taler-wire-gateway/*
+
+ All endpoints under this prefix are specified
+ by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`.
+
+ The endpoints are only available for accounts configured with ``is_exchange=true``.
+
+Taler Revenue API
+----------------------
+
+.. http:any:: /accounts/$USERNAME/taler-revenue/*
+
+ All endpoints under this prefix are specified
+ by the :doc:`GNU Taler Revenue API </core/api-bank-merchant>`.
EBICS Host Management
---------------------
diff --git a/design-documents/049-auth.rst b/design-documents/049-auth.rst
new file mode 100644
index 00000000..0aed31a9
--- /dev/null
+++ b/design-documents/049-auth.rst
@@ -0,0 +1,177 @@
+DD 49: Authentication
+#####################
+
+Summary
+=======
+
+This design document specifies a simple authentication framework to be used by multiple Taler
+components that require authentication.
+
+Motivation
+==========
+
+SPAs currently store the username and password in locals storage (or at least
+session storage).
+
+There's also no way to manage auth tokens third parties (e.g.
+auditors).
+
+Requirements
+============
+
+* simple specification
+* simple implementation
+* simple to use
+* must cover two main use cases:
+
+ * SPA login
+ * delegating (possibly restricted) access to a third party using a token
+
+Proposed Solution
+=================
+
+We define a ``token`` endpoint that can be used to obtain access tokens from
+other forms of authentication, typically HTTP Basic auth.
+
+
+.. _dd48-token:
+
+Token Endpoint
+--------------
+
+.. http:post:: /${RESOURCE...}/auth-token
+
+ **Request Body**
+
+ .. ts:def:: TokenRequest
+
+ interface TokenRequest {
+ // Service-defined scope for the token.
+ // Typical scopes would be "readonly" or "readwrite".
+ scope: string;
+
+ // Server may impose its own upper bound
+ // on the token validity duration
+ duration?: RelativeTime;
+
+ // - "session": Token with short expiration.
+ // When one session token is revoked,
+ // other session tokens might be revoked
+ // as well.
+ // - "durable": Token with longer allowed expiration.
+ // Durable tokens are explicitly and individually revoked.
+ // Defaults to "session" when the server supports session tokens.
+ kind?: "session" | "durable";
+ }
+
+ **Response:**
+
+ :http:statuscode:`200 Ok`:
+ The response is a `TokenSuccessResponse`
+
+ **Details:**
+
+ .. ts:def:: TokenSuccessResponse
+
+ interface TokenSuccessResponse {
+ // Expiration determined by the server.
+ // Can be based on the token_duration
+ // from the request, but ultimately the
+ // server decides the expiration.
+ expiration: Timestamp;
+
+ // Opque access token.
+ access_token: string;
+
+ // Token kind.
+ kind: string;
+ }
+
+Token Revocation
+-------------------------------
+
+Clients using session tokens log by forgetting the session token.
+
+.. http:post:: /${SERVICE}/auth-revoke-sessions
+
+ Revoke all session tokens.
+
+ **Authentication:** The client must authenticate
+ with a valid access token.
+
+.. http:post:: /${SERVICE}/auth-revoke-tokens
+
+ Revoke all access tokens (durable and session tokens).
+
+ **Authentication:** The client must authenticate
+ with a valid access token.
+
+
+Implementation Considerations
+-----------------------------
+
+Session Tokens
+^^^^^^^^^^^^^^
+
+Session access tokens should be implemented as "self-encoded tokens", i.e.
+as tokens signed by the server without requiring server-side token storage.
+Session access tokens should have a rather short maximum expiration.
+
+The signature should be over ``(username, kind, scope, creation_timestamp, expiry)``.
+
+To revoke session tokens, the server must store the timestamp of the last
+revocation and only accept tokens with a ``creation_timestamp`` larger than the
+last revocation timestamp. Individual session tokens cannot be revoked, only
+all issued session tokens can be revoked at once.
+
+Session tokens *may* also be implemented as server-stored tokens instead.
+
+Durable Tokens
+^^^^^^^^^^^^^^
+
+Durable tokens should be stored in a server-side database.
+
+
+Performance Considerations
+--------------------------
+
+For performance reasons, OAuth 2.0 uses two types of tokens: Short-lived access
+tokens and long-lived refresh tokens. The access tokens can be implemented via
+signatures and the long-lived refresh tokens via server-stored tokens. This
+allows to cheaply validate access tokens, while still allowing longer expiration times
+for refresh tokens.
+
+We could do something similar by introducing ``kind=login`` tokens. A login
+token is a server-stored token. In addition to being used directly as an
+access token, a login token can also be converted to a short-lived session
+token.
+
+
+Definition of Done
+==================
+
+* spec reviewed
+* implemented in merchant backend
+* implemented in libeufin-bank
+* implemented in the bank webui SPA
+* implemented in the merchant backoffice SPA
+
+
+Alternatives
+============
+
+* use something much closer to OAuth2
+
+ * would be unnecessarly generic and complex
+
+* only use durable tokens
+
+Drawbacks
+=========
+
+* still more complex than simple auth tokens or HTTP basic auth
+
+Discussion / Q&A
+================
+
+(This should be filled in with results from discussions on mailing lists / personal communication.)
diff --git a/design-documents/index.rst b/design-documents/index.rst
index 1d8a55d0..5db79a7e 100644
--- a/design-documents/index.rst
+++ b/design-documents/index.rst
@@ -58,4 +58,5 @@ and protocol.
046-mumimo-contracts.rst
047-stefan.rst
048-wallet-exchange-lifecycle.rst
+ 049-auth.rst
999-template