This document defines the old API for Device to Controller communications. The new API is defined in APIv2.md](./APIv2.md).
This document is version 1, and all endpoints will begin with /api/v1
.
API
: This API for Device-to-Controller communications.Device
: an independent computation Device that runs an engine and is controlled via a centralized control system. Normally, it runs EVE.Controller
: A centralized unit that can control one or more Devices. It can be in the cloud, on a laptop, on a Device itself, or anywhere.UUID
: A universally unique identifier for a Device within the realm of a Controller.
A Device MUST be able to boot independently of a Controller, as defined in this document. The independent boot mechanism MAY be a local flash or disk, an attached storage Device like a media card or CD/DVD, network boot, or any other method. A Controller MAY also provide boot services such as iPXE, but that is NOT part of the Controller's responsibilities according to this document.
A Device MUST register with a Controller in an agreed and secure fashion, to be detailed below. It is NOT the responsibility of the Controller to seek out and find Devices.
A Device MUST retrieve its configuration from its Controller.
A Device MUST check for updated configuration on a periodic basis. The period for refresh is implementation-dependent and is NOT defined in this document.
A Device MUST use the communications, authentication and authorization channels described in this document.
A Device MUST NOT generate its own UUID. Rather, it MUST receive its UUID from its Controller via its first config
API call. A Device MUST submit its UUID with each request other than register
and ping
, and it MUST check its current UUID against the returned UUID with each request from the config
endpoint.
A Device MUST generate its own unique Device certificate and key. This specification does NOT define the mechanism by which a Device is to do so, as it is implementation-dependent. It is RECOMMENDED that a Device use hardware security, where possible, such as TPM or TEE, to protect the Device private key.
A Device MUST have a method of knowing or discovering its Controller URL. This specification does NOT define the mechanism by which a Device is to do so, as it is implementation-dependent.
A Device MUST maintain and persist its own current state such that it survives reboots and process restarts. This includes UUID and configuration parameters. This specification does NOT define the mechanism by which each Device is to do so.
A Controller MUST be available for response to Device requests.
A Controller MUST be accessible to all Devices that need to reach it. If it cannot be accessed due to network limitations, the necessary proxies and other network traversal solutions should be made available. Those solutions are implementation-dependent and are not defined in this specification.
A Controller MUST listen for https on a port. The specific port is not specified in this document, however, it is RECOMMENDED to use the well-known https port of 443 where possible. A Controller MUST expose all of the endpoints listed in this document. A Controller MAY additionally listen on other ports, and MAY expose additional endpoints defined in this document, provided those endpoints do NOT conflict with those defined in this document, and use the "Extensions" provision listed herein.
A Controller MUST generate a UUID for each Device. The UUID MUST be unique across all Devices managed by the Controller. The Controller SHOULD use an approach to generating UUIDs which minimizes the probability of UUID collisions with UUIDs generated by all Controllers everywhere.
All messages are defined in subdirectories to the proto directory. In general, there is one directory for each API endpoint:
register
: The register message sent as part of onboarding a deviceconfig
: The ConfigRequest message sent from the device and the ConfigResponse with EdgeDevConfig message sent from Controller to Device in response.info
: The ZInfoMsg message sent from Device to Controller when there is a state change for an object (device, app instance, etc )metrics
: The ZMetricMsg message sent from Device to Controller periodically to report on resource usage etc.logs
: The LogBundle message sent from Device to Controller containing internal device logs.apps/instances/{app-instance-uuid}/logs
: The LogBundle message sent from Device to Controller containing application console device logs.certs
: The ZControllerCert message is sent from Controller to Device, and contains the list of certificates used by Controller. Each ZControllerCert message replaces the current list on EVE with the new list of certificates. Therefore, if an empty list is sent, it resets the list on the receiving side.attest
: This API anchors all trust and attestation operations from EVE. At the top level, EVE does a POST ofZAttestReq
and getsZAttestResp
as the response from Controller.ZAttestReq
supports 3 types of requests:ATTEST_REQ_CERT
is for sending certificates used by EVE,ATTEST_REQ_NONCE
is for nonce request,ATTEST_REQ_QUOTE
is for sending attestation quote.ZAttestResponse
is the response from Controller forZAttestReq
.ZAttestResp
also has 3 response types:ATTEST_RESP_CERT
is response for posting EVE certificates,ATTEST_RESP_NONCE
carries the nonce requested by EVE, andATTEST_RESP_QUOTE
carries the result of remote attestation.ZAttestQuote
carries PCR Quote generated by Trusted Platform Module.ZEveCert
encapsulates an EVE certificate, with a set of attributes listed byZEveCertAttr
. IfisMutable
attribute is not set, a certificate once posted can not be overwritten by another certificate of the sameZEveCertType
. This attribute can be used to prevent compromised EVE from replacing its certs in the Controller, probably to use software based certs instead of certs rooted in Trusted Platform Module.
All communication messages MUST be encrypted with TLS v1.2 or higher, and MUST authenticate all message with mutual TLS (mTLS). It is RECOMMENDED to use TLS v1.3 or higher to provider better privacy for the Device certificate and faster communication initialization.
There are two types of certificates to use for client authentication via mTLS:
- Onboarding: These MUST be used only for initial Device registration via the
/register
endpoint or for the/ping
endpoint prior to registration, and MUST NOT be used again thereafter. - Device: These MUST be used for all communications after the initial Device registration.
A Controller MUST NOT expose any endpoints that do not offer TLS encryption. A Controller MUST NOT offer any endpoints in the edge device path /api/v1/edgedevice/
that do not use mTLS authentication.
The ping
endpoint may be useful for a Device to check connectivity before registering. Since the device has not yet registered, it MUST use its onboarding certificate to authenticate to the ping
endpoint. The Controller SHOULD rate limit the endpoint when authenticated via onboarding certificate. A Device MUST expect that its Controller may rate limit the ping
endpoint, and have an appropriate backoff scheme for retrying.
The common return codes for failed authentication or authorization are:
- In the case of a missing or invalid client certificate, a Controller MUST return a
401
http error code. - In the case of a valid client certificate but an endpoint to which the certificate does NOT have access, whether an endpoint listed in this specification or a custom endpoint, a Controller MUST return a
403
http error code.
Additional return codes are defined in this specification for each endpoint as necessary.
A Controller MAY offer additional API endpoints under the path /ext
after the /api
and version prefix. This is to ensure no conflict with existing or future official endpoints.
For example, an endpoint called "custom" would be:
GET /api/v1/ext/custom
An endpoint specific called "check" specific to edge devices would be:
GET /api/v1/edgedevice/ext/check
Because the endpoint is under the /edgedevice/
path, it MUST be encrypted and mTLS authenticated.
All GET
requests MUST have no mime type set.
All POST
requests MUST have the mime type set of application/x-proto-binary
.
All responses with a body MUST have the mime type set of application/x-proto-binary
.
The following are the API endpoints that MUST be implemented by a Controller. All of these endpoints MUST be encrypted and authenticated.
Register a new Device for the first time.
POST /api/v1/edgeDevice/register
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Valid registration:
201
- Repeat valid registration for Device:
200
- Duplicate Device:
409
- Missing or unprocessable body:
422
Request:
The request MUST use the onboarding certificate for mTLS authentication. The Controller MAY retain the onboarding certificate or information within it for further purposes.
The request mime type MUST be "application/x-proto-binary". The request MUST have the body of a single protobuf message of type register.ZRegisterMsg. The message MUST include the Device certificate. In the case where the Device certificate is the same as the onboarding certificate, the Device MUST NOT assume that the Controller will extract the Device certificate from the mTLS authentication, and instead it MUST include the certificate in the message.
The message SHOULD include a serial string or other unique identifier for the Device.
The combination of onboard certificate and serial MUST be unique to each Device. Each item on its own, serial or onboard certificate, MAY be duplicated. In the case of an attempt to register a combination of onboard certificate+serial that already has been registered:
- If the proposed device certificate is identical to the one already registered, then the Controller MUST return a "OK 200" status code.
- If the proposed device certificate is different from the one already registered, then the Controller MUST return a "Conflict 409" status code.
A Controller MAY require pre-registration of onboarding certificates, serial or a combination thereof prior to accepting a Device register request. In the case where a Controller requires pre-registration, yet a Device attempts to use the register
endpoint prior to pre-registration, a Controller MUST return an "Unauthorized 403".
This specification recognizes two use cases for device registration:
- Onboarding: A Device with an appropriate onboarding certificate and serial string can register. The Device calls the
/register
endpoint to register its unique device certificate. - Registered: A Device with a unique device certificate has already had its certificate registered with the Controller. The Device does not call the
/register
endpoint, as it already is registered. Instead, it moves directly to the/config
endpoint to retrieve its configuration.
Additional registration flows, including a unique Device certificate signed by a CA recognized by the Controller, and a CSR-based flow, are under consideration for future versions of this specification.
Response:
The response MUST NOT contain any body content.
Check connectivity between Device and Controller.
GET /api/v1/edgeDevice/ping
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
200
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST NOT contain any body content.
Response:
The response MUST NOT contain any body content.
Retrieve configuration for a specific Device.
POST /api/v1/edgeDevice/config
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
200
- Unknown Device:
400
Request:
The request MUST use the Device certificate for mTLS authentication.
The request mime type MUST be "application/x-proto-binary". The request MUST have the body of a single protobuf message of type config.ConfigRequest. The message should include the previous configHash from a previous ConfigResponse message to reduce network utilization when there is no configuration change.
Response:
The response mime type MUST be "application/x-proto-binary". The response MUST contain a single protobuf message of type config.ConfigResponse. If the configHash is the same as in the ConfigRequest then the EdgeDevConfig should not be included. Otherwise the EdgeDevConfig will contain the entire configuration for the given Device. The response body MUST contain the UUID for the Device unless the configHash is the same. The Controller MUST NOT assume that the Device already has the UUID.
GET /api/v1/edgeDevice/config
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
200
- Unknown Device:
400
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST NOT contain any body content.
Response:
The response mime type MUST be "application/x-proto-binary". The response MUST contain a message with the entire configuration for the given Device. The body MUST be a protobuf message of type config.EdgeDevConfig. The body MUST contain the entire configuration for the Device. The body MUST contain the UUID for the Device on each and every request. The Controller MUST NOT assume that the Device already has the UUID.
The config
endpoint, specifically the EdgeDevConfig
message, supports arbitrary key/value pairs. These are intended to send implementation-specific configuration to a Device. For example, it might control the frequency of downloading configs, enable debug logging or enable a USB port.
The EdgeDevConfig
message can contain zero, one or more ConfigItem
entries, each of which is an arbitrary key/value pair. These SHOULD be used to send implementation-specific configuration to a Device, other than configuration already defined in this API or the messages. The items are defined in configuration properties
Retrieve Certificates that Controller will use. Controller can include one or more certificates in the response, and include information about each certificate such as unique identifier for the certificate, the target usage for the certificate and any other properties related to the certificate. Each certificate MUST be a X.509 certificate in PEM format. The device will verify the certificate chains against its trusted root certificate.
GET /api/v1/edgeDevice/certs
Return codes:
- No such certificates to send:
404
- One or more certificates found:
200
Request:
The request MUST use HTTP for this request
The request MUST NOT contain any body content
Response:
The response mime type MUST be "application/x-proto-binary". The response MUST contain a message with a list of certificates Controller is using. The body MUST be a protobuf message of type certs.ZControllerCert.
This API anchors all operations related to attestation and trust of a device
POST /api/v1/edgeDevice/id/{uuid}/attest
Return codes:
- Unauthenticated or invalid credentials:
401
- Success:
201
- Unknown Device:
400
- Missing or unprocessable body:
422
Request:
The request mime type MUST be "application/x-proto-binary".
The body MUST be a protobuf message of type attest.ZAttestReq.
ZAttestReq
has reqType
which MUST be filled by EVE to identify type of the request. If reqType
is ATTEST_REQ_CERT
, certs
should be filled with certificates used by EVE. If isIMutable
attribute is not set, Controller should reject any request that would overwrite an existing certificate previously published. If reqType
is ATTEST_REQ_NONCE
, no other field needs to be set in ZAttestReq
. If reqType
is ATTEST_REQ_QUOTE
, then quote
MUST be populated with the quote generated by Trusted Platform Module.
Response:
The request mime type MUST be "application/x-proto-binary".
The body MUST be a protobuf message of type attest.ZAttestResp.
ZAttestResp
has respType
which MUST be filled by Controller. If respType
is ATTEST_RESP_CERT
, no other field needs to be set. If respType
is ATTEST_RESP_NONCE
, nonce field MUST be set. If respType
is ATTEST_RESP_QUOTE
, then quoteResp
MUST be filled with the result of the attestation.
Send Device status information to Controller
POST /api/v1/edgeDevice/info
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
201
- Unknown Device:
400
- Missing or unprocessable body:
422
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST be of mime type "application/x-proto-binary".
The request body MUST be a protobuf message of type info.ZInfoMsg. The message itself MUST be one of the types defined as info.ZInfoTypes.
The request body MUST indicate the type of information it is sending, and the content thereof. It MUST be one of:
- Device via
ZInfoDevice
: information about the Device itself, including baseos version, update of baseos, etc. - Application via
ZInfoApp
: information about an application running on the Device, including running, started, stopped, downloaded, version, etc. - Network via
ZInfoNetworkInstance
: information about networking on the Device, including ports, connectivity, assignment, etc.
An information message is expected to be reliable. A Device MUST retry until it successfully delivers information messages. How often information messages are sent, retries and other caching mechanisms on the Device are NOT specified here, as they are implementation questions.
Response:
The response MUST contain no body content.
Send Device and Application metrics to Controller
POST /api/v1/edgeDevice/metrics
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
201
- Unknown Device:
400
- Missing or unprocessable body:
422
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST be of mime type "application/x-proto-binary".
The request body MUST be a protobuf message of type metrics.ZMetricMsg. The message itself contains metrics of the following combinations:
- zero or one Device metrics
DeviceMetric
- zero, one or many application metrics
appMetric
- zero, one or many network metrics
ZMetricNetworkInstance
A metrics message is NOT expected to be reliable. A Device SHOULD expect that some metrics messages will be lost. A Controller MUST NOT expect that it has received all of the metrics from a Device. Metric values in a metrics message SHOULD be cumulative, such that the loss of one or more metrics messages results in the loss of precision in the time domain alone, and not in the loss of any other information.
A Device SHOULD bundle many metrics together into a single ZMetricMsg
. The choice of how many to bundle together, and how often to send them, is implementation-dependent.
Response:
The response MUST contain no body content.
Send Device logs to Controller
POST /api/v1/edgeDevice/logs
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
201
- Unknown Device:
400
- Missing or unprocessable body:
422
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST be of mime type "application/x-proto-binary".
The request body MUST be a protobuf message of type log.LogBundle. The message itself contains zero, one or more entries of type log.LogEntry.
Each LogEntry
is a single log message indicating its timestamp, source, severity, message ID, application or process ID, and arbitrary message content. In addition, it can content an unlimited number of key/value pairs.
A Device SHOULD bundle many log messages together into a single LogBundle
.
A LogBundle
MUST NOT be larger than the maximum size specified by the Controller for the Device, but MAY be smaller than that, if insufficient messages are available or the Device network or endpoints cannot handle the maximum size. The Device MUST retrieve the maximum LogBundle
message size from the appropriate field of the configuration.
A log message is expected to be reliable. A Device MUST retry until it successfully delivers log messages. How often log messages are sent, retries, the number of messages and which types to bundle together into a single LogBundle
, and other caching mechanisms on the Device are NOT specified here, as they are implementation questions.
Response:
The response MUST contain no body content.
Send Application logs to Controller
POST /api/v1/edgeDevice/apps/instances/{app-instance-uuid}/logs
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
201
- Unknown Application Instance:
400
- Missing or unprocessable body:
422
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST be of mime type "application/x-proto-binary".
The request body MUST be a protobuf message of type log.AppInstanceLogBundle. The message itself contains zero, one or more entries of type log.LogEntry.
Each LogEntry
is a single log message indicating its timestamp, source, severity, message ID, application or process ID, and arbitrary message content. In addition, it can contain an unlimited number of key/value pairs.
A Device SHOULD bundle many log messages together into a single LogBundle
.
A LogBundle
MUST NOT be larger than the maximum size specified by the Controller for the Device, but MAY be smaller than that, if insufficient messages are available or the Device network or endpoints cannot handle the maximum size. The Device MUST retrieve the maximum LogBundle
message size from the appropriate field of the configuration.
A log message is expected to be reliable. A Device MUST retry until it successfully delivers log messages. How often log messages are sent, retries, the number of messages and which types to bundle together into a single LogBundle
, and other caching mechanisms on the Device are NOT specified here, as they are implementation questions.
Response:
The response MUST contain no body content.
The flowlog API is used by the device to send network flow statistics (TCP and UDP flows with IP addresses, port numbers, counters, whether dropped or accepted), and also the hostname to IP address mapping as seen by the device.
POST /api/v1/edgeDevice/flowlog
Return codes:
- Unauthenticated or invalid credentials:
401
- Valid credentials without authorization:
403
- Success:
201
- Unknown Device:
400
- Missing or unprocessable body:
422
Request:
The request MUST use the Device certificate for mTLS authentication.
The request MUST be of mime type "application/x-proto-binary".
The request body MUST be a protobuf message of type flowlog.FlowMessage. The message itself contains zero or more entries of type flowlog.FlowRecord and/or zero or more entries of type flowlog.DnsRequest.
A FlowMessage
MUST NOT be larger than the maximum size specified by the Controller for the Device, but MAY be smaller than that, if insufficient messages are available or the Device network or endpoints cannot handle the maximum size. The Device MUST retrieve the maximum FlowMessage
message size from the appropriate field of the configuration.
A flowlog message is expected to be reliable. A Device MUST retry until it successfully delivers log messages. However, if there is more recent information for flows, e.g., updated counters, that information can be sent instead of retransmitting old information as long as no flows are omitted. How often log messages are sent, retries, the number of entries to bundle together into a single FlowMessage
, and other caching mechanisms on the Device are NOT specified here, as they are implementation questions.
Response:
The response MUST contain no body content.
Edge Devices are expected to have intermittent connectivity, with limited bandwidth, memory and storage. It is likely that, at some point, a Device will run out of local memory or storage to cache information, logs or metrics messages that need to be sent to a Controller.
The choice of which messages to keep, how long to keep them, which to discard, and how to handle these overflows are implementation-dependent and are NOT specified in this document.
Edge Devices may send some MetaData in HTTP header to the controller. This will help the controller side troubleshooting at the HTTP level. The Device UUID can be included in the HTTP header 'X-Request-ID'. Since the UUID on Device is obtained from the controller, when the UUID is not available yet, the Device Serial-Number and Soft-Serial-Number can be included in the HTTP header fields 'X-Serial-Number' and 'X-Soft-Serial' respectively.