# Principles of API Design Inspired by Kubernetes, this document aims to articulate some core principles that make APIs scalable, extensible, and flexible for long-term evolution. At its core, Kubernetes implements an [actor model][actormodel] paradigm using a single API server architecture. Data types can be observed in the API server by [_controllers_][controller], which then _act_ upon the new or modified resource, or on other resources in its domain. Each time a change is introduced on a data resource in the API, the controller _reconciles_ the new (desired) state from the previous state, and makes any necessary changes in its domain. The domain of a controller is either within Kubernetes, acting on other data resources in the API, or systems outside of Kubernetes, such as creating a virtual machine or storage bucket. This model allows a single architecture to grow and evolve within a single application domain, and to be extended into new domains when new data types are created, and new controllers created to interact with them. Overarching principles: * Adopt the [actor model][actormodel] as a paradigm; make each data type the responsibility of a dedicated component, and let components interact only through a single, centralized data model. * Each actor should have strict, narrowly defined responsibilities for a limited number of data types; ideally a single data type per actor. In practices, actors may require _input_ of one datatype, and _output_ to another. * The *status* of a data resource must present a well-known structure, so that other observers of that data type can behave correctly based on the lifecycle of each resource dependency, and new observers can easily be created to integrate them. * Reconciliation (evaluating desired state versus current state) should drive the actors' actions upon their domains, to achieve the desired state. ## Access Control Kubernetes' role-based access control brilliantly corresponds to the actor model. Each actor has a discrete identity in the system (a service account, in Kubernetes). Permissions are declared using roles. Actors are granted permissions by _binding_ their identity to a role. Notably, Kuberentes' authentication capabilities are oriented primarily to _delegated_ authentication with other systems via OIDC, SAML, etc. For service accounts, Kubernetes can used token-based and certificate-based authentication; the component identity is encoded into a certificate which is signed by Kubernetes' CA. In practice, this means Kuberentes maintains **no concept** of user accounts, and relies only on certificate validation for system components. ## Versioning and Upgradability Kubernetes resource types are declared using a _group-version-kind_ (GVK) taxonomy. Each data type is named (given a "Kind"), and belongs to a _versioned group_ that coevolves. For example, in Kubernetes: ```yaml apiVersion: apps/v1 # this is the group-version kind: Deployment # this is the kind ... ``` An API group is expected to change over time, and therefore declares a version. Data resources declare their own GVK, which specifies how they will be marshalled into a data structure; it indicates their schema. The stored representation of the resource includes this schema information; the API server is responsible for storing the resource after validating its content against its schema. Additional validation may be provided using a _validating webhook_, which is performed before the resource is stored. When controllers load a resource from storage, the resource may first be transparently _upgraded_ (if needed) to the group-version the controller supports. The controller receives a representation in the schema it expects. The upgrade process of a data model is defined in a separate component, which is called by the API server when loading a resource, to convert it from its stored schema to the expected schema of each controller that reads it. The stored representation does not change until the resource is rewritten. Controllers (actors) can be versioned independently from the APIs they support, provided they maintain the behavioral compatibility guarantees associated with the API version. Strict conventions are defined on API versioning: * _Alpha_ * Any alpha version may add optional fields at any time. * Alpha APIs may remove any field when the version is bumped to the next alpha. * An upgrade path is not required, but strongly encouraged, between alpha versions. * An alpha version must be supported for at least 1 release period. * No compatibility guarantees are made for clients. * _Beta_ * Beta versions may add optional fields when the version is bumped to the next beta. * Beta versions must not remove required fields, and must not change the resulting behavior of any required field. * Upgrade paths are required between beta versions. * A beta version must be supported for the greater of 9 months or 3 release periods, and requires a 6 month deprecation notice. * Multiple beta API versions will be supported simultaneously, to support upgrades. * _GA_ * GA versions are supported indefinitely. Long-term compatibility is guaranteed, as third-party clients, or other system components, will rely heavily on GA APIs for business-critical operations. * Deprecating a GA API requires 1 year deprecation notice, and comprehensive API migration for all suported use-cases to a replacement API, that reaches GA before the start of the 1 year deprecation cycle. When we say an API version is supported, this means clients can still interact with the system using these APIs. There may be newer APIs doing something better or differently in the same domain, but the API they're built against is reliable for the given period. Upgradability is achieved by: * Overlapping the support periods of two versions of the API; this is required for Beta and GA. * Data model upgrade automation is required for Beta and GA versions. * A deprecated API version must still be supported for at least 1 release during which its successor is also supported. [actormodel]: https://en.wikipedia.org/wiki/Actor_model [controller]: https://kubernetes.io/docs/concepts/architecture/controller/