API

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.

Definitions

  1. API: This API for Device-to-Controller communications.
  2. Device: an independent computation Device that runs an engine and is controlled via a centralized control system. Normally, it runs EVE.
  3. 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.
  4. UUID: A universally unique identifier for a Device within the realm of a Controller.

Responsibilities

Device

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.

Controller

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.

Messages

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 device
  • config: 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 of ZAttestReq and gets ZAttestResp 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 for ZAttestReq. ZAttestResp also has 3 response types: ATTEST_RESP_CERT is response for posting EVE certificates, ATTEST_RESP_NONCE carries the nonce requested by EVE, and ATTEST_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 by ZEveCertAttr. If isMutable attribute is not set, a certificate once posted can not be overwritten by another certificate of the same ZEveCertType. 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.

Authentication

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.

Extensions

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.

Mime Types

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.

Endpoints

The following are the API endpoints that MUST be implemented by a Controller. All of these endpoints MUST be encrypted and authenticated.

Register

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.

Ping

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.

Configuration

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.

Configuration (deprecated GET method)

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.

Arbitrary Config Variables

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

Controller Certificates

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.

Attestation

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.

Info

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.

metrics

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.

logs

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.

Application Instance logs

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.

flowlog

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.

Caching Policy

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.

HTTP MetaData

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.