-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from ethereum/dapplion/keymanager
Add keymanager-oapi.yaml
- Loading branch information
Showing
1 changed file
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
openapi: "3.0.3" | ||
|
||
info: | ||
title: "Eth2 key manager API" | ||
description: | | ||
API specification for a key manager client, which enables users to manage keystores. | ||
The key manager API is served by the binary holding the validator keys. This binary may be a remote signer or a validator client. | ||
All routes SHOULD be exposed through a secure channel, such as with HTTPs, an SSH tunnel, a VPN, etc. | ||
All requests by default send and receive JSON, and as such should have either or both of the "Content-Type: application/json" | ||
and "Accept: application/json" headers. | ||
All sensitive routes are to be authenticated with a token. This token should be provided by the user via a secure channel: | ||
- Log the token to stdout when running the binary with the key manager API enabled | ||
- Read the token from a file available to the binary | ||
version: "Dev - Eth2Spec v1.0.1" | ||
contact: | ||
name: Ethereum Github | ||
url: https://github.com/ethereum/eth2.0-apis/issues | ||
license: | ||
name: "Apache 2.0" | ||
url: "https://www.apache.org/licenses/LICENSE-2.0.html" | ||
|
||
servers: | ||
- url: "{server_url}" | ||
variables: | ||
server_url: | ||
description: "key manager API url" | ||
default: "https://public-mainnet-node.ethereum.org" | ||
|
||
paths: | ||
/eth/v1/keystores: | ||
get: | ||
operationId: ListKeys | ||
summary: List Keys. | ||
description: | | ||
List all validating pubkeys known to and decrypted by this keymanager binary | ||
security: | ||
- cookieAuth: [] | ||
responses: | ||
"200": | ||
description: Success response | ||
content: | ||
application/json: | ||
schema: | ||
title: ListKeysResponse | ||
type: object | ||
properties: | ||
data: | ||
type: array | ||
items: | ||
type: object | ||
properties: | ||
validating_pubkey: | ||
$ref: "#/components/types/Pubkey" | ||
derivation_path: | ||
type: string | ||
description: The derivation path (if present in the imported keystore). | ||
readonly: | ||
type: boolean | ||
required: false | ||
description: The key associated with this pubkey cannot be deleted from the API | ||
|
||
"401": | ||
$ref: "#/components/responses/Unauthorized" | ||
"403": | ||
$ref: "#/components/responses/Forbidden" | ||
"500": | ||
$ref: "#/components/responses/InternalError" | ||
|
||
post: | ||
operationId: ImportKeystores | ||
summary: Import Keystores. | ||
description: | | ||
Import keystores generated by the Eth2.0 deposit CLI tooling. `passwords[i]` must unlock `keystores[i]`. | ||
Users SHOULD send slashing_protection data associated with the imported pubkeys. MUST follow the format defined in | ||
EIP-3076: Slashing Protection Interchange Format. | ||
security: | ||
- cookieAuth: [] | ||
requestBody: | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
keystores: | ||
type: array | ||
description: JSON-encoded keystore files generated with the Launchpad. | ||
items: | ||
type: object | ||
passwords: | ||
type: array | ||
description: Passwords to unlock imported keystore files. `passwords[i]` must unlock `keystores[i]`. | ||
items: | ||
type: string | ||
slashing_protection: | ||
type: object | ||
required: false | ||
description: Slashing protection of the imported keys data in EIP-3076 JSON format. | ||
responses: | ||
"200": | ||
description: Success response | ||
content: | ||
application/json: | ||
schema: | ||
title: ImportKeystoresResponse | ||
type: object | ||
properties: | ||
data: | ||
type: array | ||
description: Status result of each `request.keystores` with same length and order of `request.keystores` | ||
items: | ||
type: object | ||
properties: | ||
status: | ||
type: string | ||
description: | | ||
- imported: Keystore successfully decrypted and imported to keymanager permanent storage | ||
- duplicate: Keystore's pubkey is already known to the keymanager | ||
- error: Any other status different to the above: decrypting error, I/O errors, etc. | ||
enum: | ||
- imported | ||
- duplicate | ||
- error | ||
message: | ||
type: string | ||
description: error message if status == error | ||
"401": | ||
$ref: "#/components/responses/Unauthorized" | ||
"403": | ||
$ref: "#/components/responses/Forbidden" | ||
"500": | ||
$ref: "#/components/responses/InternalError" | ||
|
||
delete: | ||
operationId: DeleteKeys | ||
summary: Delete Keys. | ||
description: | | ||
DELETE must delete all keys from `request.pubkeys` that are known to the keymanager and exist in its | ||
persistent storage. Additionally, DELETE must fetch the slashing protection data for the requested keys from | ||
persistent storage, which must be retained (and not deleted) after the response has been sent. Therefore in the | ||
case of two identical delete requests being made, both will have access to slashing protection data. | ||
In a single atomic sequential operation the keymanager must: | ||
1. Guarantee that key(s) can not produce any more signature; only then | ||
2. Delete key(s) and serialize its associated slashing protection data | ||
DELETE should never return a 404 response, even if all pubkeys from request.pubkeys have no extant keystores | ||
nor slashing protection data. | ||
security: | ||
- cookieAuth: [] | ||
requestBody: | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
pubkeys: | ||
type: array | ||
description: List of public keys to delete. | ||
items: | ||
$ref: "#/components/types/Pubkey" | ||
responses: | ||
"200": | ||
description: Success response | ||
content: | ||
application/json: | ||
schema: | ||
title: DeleteKeysResponse | ||
type: object | ||
properties: | ||
data: | ||
type: array | ||
description: Deletion status of all keys in `request.pubkeys` in the same order. | ||
items: | ||
type: object | ||
properties: | ||
status: | ||
type: string | ||
description: | | ||
- deleted: key was active and removed | ||
- not_active: slashing protection data returned but key was not active | ||
- not_found: key was not found to be removed, and no slashing data can be returned | ||
- error: unexpected condition meant the key could not be removed (the key was actually found, but we couldn't stop using it) - this would be a sign that making it active elsewhere would almost certainly cause you headaches / slashing conditions etc. | ||
enum: | ||
- deleted | ||
- not_active | ||
- not_found | ||
- error | ||
message: | ||
type: string | ||
description: error message if status == error | ||
slashing_protection: | ||
type: object | ||
description: | | ||
JSON representation of the slash protection data in format defined in EIP-3076: Slashing | ||
Protection Interchange Format. | ||
"401": | ||
$ref: "#/components/responses/Unauthorized" | ||
"403": | ||
$ref: "#/components/responses/Forbidden" | ||
"500": | ||
$ref: "#/components/responses/InternalError" | ||
|
||
components: | ||
responses: | ||
Unauthorized: | ||
$ref: "./types/http.yaml#/Unauthorized" | ||
Forbidden: | ||
$ref: "./types/http.yaml#/Forbidden" | ||
InternalError: | ||
$ref: "./types/http.yaml#/InternalError" | ||
|
||
securitySchemes: | ||
cookieAuth: # arbitrary name for the security scheme; will be used in the "security" key later | ||
type: apiKey | ||
in: cookie | ||
name: SESSION # cookie name | ||
|
||
types: | ||
Pubkey: | ||
type: string | ||
pattern: "^0x[a-fA-F0-9]{96}$" | ||
description: "The validator's BLS public key, uniquely identifying them. _48-bytes, hex encoded with 0x prefix, case insensitive._" | ||
example: "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" |