Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keymanager-oapi.yaml #2

Merged
merged 1 commit into from
Nov 10, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 229 additions & 0 deletions keymanager-oapi.yaml
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"