diff --git a/5.0 Draft/IDD/IDDs Authorization System/eu.arrowhead.authorization-http-json.yml b/5.0 Draft/IDD/IDDs Authorization System/eu.arrowhead.authorization-http-json.yml new file mode 100644 index 0000000..9465fb2 --- /dev/null +++ b/5.0 Draft/IDD/IDDs Authorization System/eu.arrowhead.authorization-http-json.yml @@ -0,0 +1,370 @@ +openapi: 3.0.3 + +info: + title: Authorization HTTP(S)-JSON + description: | + This specification outlines how to realize the _Arrowhead Core Authorization_ service on top of + either of the HTTP or HTTPS protocols with payloads encoded in JSON. This service allows for + _resource_ ownwers to check _access-rights_ of _subjects_ attempting to perform operations over + their protected _resources_. Authorization queries are then made in the form of the _triple_ + (subject, access-right, resource). In the context of service consumption authorization, + service providers act as resource owners for their provideded services (or _resources_), while + consumers are _subjects_ trying to apply their _access right_ to consume a service. For such + application, an authorization query shall look as: + + subject: "MWtzOXIpaUEsOyEhc1NsTwo=" + access-right: "consume" + resource: "/OutsideTemp" + + In the context of this document, we understand an _access-right_ to be a string identifier that + names something a subject can request that a certain type of service performs on its behalf. We + also understand an _resource_ to be any kind resource that is acted upon while an operation is + performed. If, for example, a file storage service is provided, then possible _access-right_ could + be `"upload"` and `"download"` while the _resource_ of the service are the files it stores. + + No requirements are imposed on an implementation of this service with regards to how it + determines if certain subjects are allowed to perform certain access rights on certain resources. + It may implement something akin to the INCITS 565-2020 standard, also known as _Next Generation_ + _Access Control_ (NGAC), or something much less sophisticated. It is also assumed that the + service provider is informed about what authorization requests to approve via some other service + than this one. + + ## Caching and Performance + + Implementations of this service _may_ allow for its consumers to cache its authorization + decisions for brief periods of time when relevant to improve performance. When it is enabled, it + is communicated via the `Cache-Control` header of its responses. + + An individual implementation of this service with sufficiently sophisticated software and + hardware should be able to handle up to and beyond hundreds of thousands of authorization + triplets per second. That being said, there could be cases where no available hardware is + performant enough, or where individual consumers are disconnected from this service for + significant periods of time. These use cases are outside the scope of this service. + + ## Compression and Language + + An implementation of this service interface _should_ be designed to support compression and + _may_ provide human-readable error texts in different languages than English, as described in + [RFC 9110, Section 12](https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation). Not + using compression _must_ be supported and _should_ be the default. Also, the default language + for error messages _must_ be American English (`en-US`). + + ## Size Limits + + As a mitigation against denial-of-service attacks, all implementations of this service + interface _should_ reject incoming requests that are larger than a predefined limit. That limit + _must not_ be smaller than 8192 bytes for each received request. An implementation _may_ also + limit the sizes of individual parts within each request. It _must_, however, receive request + payloads up to 4096 bytes in size. If payload compression is supported, then this limit applies + after decompression. + version: 5.0.0-rc.1 + +paths: + + /ping: + get: + summary: Endpoint to check the core system availability. + description: Returns an OK to indicate that the core system is available. + responses: + '200': + description: OK + + /authorizations: + post: + summary: Bulk Authorize access rights for Resources + description: | + Allows for bulk authorization requests to be sent to the authorization system in a single API request + + Queries the authorization system for authorization decision for each specified access right over the + specified subject and resource pair. + + As a reponse, for each request in the request body, an authorization decision will be returned. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccessRequests' + examples: + example1: + summary: Three authorization requests from different users to different resources. + value: + - subject: "user123" + access-right: "write" + resource: "eu.arrowhead.tempreadings-http-json@MWtzOXIpaUEsOyEhc1NsTwo" + - subject: "MWtzOXIpaUEsOyEhc1NsTwo=" + access-right: "consume" + resource: "/OutsideTemp" + - subject: "user789" + access-right: "read" + resource: "91" + example2: + summary: a single authorization request. + value: + subject: "user234" + access-right: "read" + resource: "document4" + responses: + '200': + description: Successful authorization + content: + application/json: + schema: + type: object + properties: + authorizationDecisions: + type: array + items: + type: string + enum: + - allowed + - denied + examples: + example1: + value: + authorizationDecisions: ["allowed", "denied"] + summary: Example response with both allowed and denied decisions + example2: + value: + authorizationDecisions: ["allowed", "allowed", "denied"] + summary: Example response with multiple decisions + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + Limit: + $ref: '#/components/headers/Limit' + '400': { $ref: '#/components/responses/400-BadRequest' } + '401': { $ref: '#/components/responses/401-Unauthorized' } + '403': { $ref: '#/components/responses/403-Forbidden' } + '406': { $ref: '#/components/responses/406-NotAcceptable' } + '408': { $ref: '#/components/responses/408-RequestTimeout' } + '411': { $ref: '#/components/responses/411-LengthRequired' } + '413': { $ref: '#/components/responses/413-PayloadTooLarge' } + '414': { $ref: '#/components/responses/414-URITooLarge' } + '415': { $ref: '#/components/responses/415-UnsupportedMediaType' } + '429': { $ref: '#/components/responses/429-TooManyRequests' } + '431': { $ref: '#/components/responses/431-RequestHeaderFieldsTooLarge' } + '500': { $ref: '#/components/responses/500-InternalServerError' } + '503': { $ref: '#/components/responses/503-ServiceUnavailable' } + +components: + + headers: + + Cache-Control: + description: | + If present, the value of this header may only include the `max-age`, `must-revalidate` and + `no-store` response directives, all of which are defined in + [RFC 9111 Section 5.2.2](https://datatracker.ietf.org/doc/html/rfc9111#name-response-directives). + + The `max-age` directive indicates for how many seconds the decision in the response may be + cached before being requested again by the subject. The `must-revalidate` directive is used + to forbid the subject from using the decision after the `max-age` has expired and the + attempt to request it again failed. The `no-store` directive instructs the subject not to + cache the decision at all. + schema: + type: string + example: max-age=10, must-revalidate + required: false + + Limit: + description: | + An indication of the maximum number of triplets the consuming system is allowed to include + in its request. + schema: + type: number + format: int32 + minimum: 0 + required: true + + Retry-After: + description: | + An indication, in seconds, of how long a subject is to wait before attempting the failed + request again. + schema: + type: number + format: int32 + minimum: 1 + required: true + + responses: + + 400-BadRequest: + description: | + Invalid authorization basis submitted in request for an authorization decision. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 401-Unauthorized: + description: | + Consumer not yet authorized. + + The kind of authorization required _may_ be named in the error response. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 403-Forbidden: + description: | + Consumer is authorized, but lacks permission. + + If a particular parameter is the cause of this error, it will be named in the payload of the + error response. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 406-NotAcceptable: + description: | + A request contains either of the `Accept`, `Accept-Encoding` or `Accept-Language` headers, + and they do not allow for the service provider to respond using `application/json` as + `Content-Type` or with an encoding or language that the service provider supports. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 408-RequestTimeout: + description: | + A request did not arrive in full within an arbitrary timeout decided by the provider of this + service interface. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 411-LengthRequired: + description: | + The `Content-Length` header is missing in the request. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 413-PayloadTooLarge: + description: | + The payload in the request exceeds the size limit imposed by the service provider. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 414-URITooLarge: + description: | + The size of the request line in the request, which includes the HTTP version, method and + URI, exceeds the limit imposed by the service provider. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 415-UnsupportedMediaType: + description: | + The request includes a payload encoded using a `Content-Type` unsupported by the service + provider. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 429-TooManyRequests: + description: | + The consumer has sent too many request in a too short time span. The consumer is expected to + wait the amount of time indicated in the `Retry-After` header before trying again. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + headers: + Retry-After: + $ref: '#/components/headers/Retry-After' + + 431-RequestHeaderFieldsTooLarge: + description: | + The headers section in the request exceeds the limit imposed by the service provider. This + response code may indicate that + + 1. either the name or value of a field is too large, + 2. the combination of name and value in a field is too large, or + 3. the complete header section is too large. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 500-InternalServerError: + description: | + The server encountered an unexpected condition that prevented it from fulfilling the + request. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 503-ServiceUnavailable: + description: | + The service provider is currently near its operating capacity or is undergoing maintenance. + The consumer is expected to wait before trying again, as indicated by the `Retry-After` + header in the response. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + headers: + Cache-Control: + $ref: '#/components/headers/Retry-After' + + schemas: + + AccessRequests: + description: An array of authorization Triplets to be submitted to the Authorization system + type: array + items: + $ref: '#/components/schemas/Triplet' + + Address: + description: | + Identifies a _transport_ and a _location_. + + The _transport_ identifies the base protocol that facilitates addressing a specific service + instance. Examples of transports that can be supported are `tcp4`, `tcp6`, `udp4`, `udp6` + and `unix`. A protocol only counts as a transport if it both (A) provides a way of + addressing and, by extension, sending messages to service providers and consumers, as well + as (B) does not build upon another protocol also providing this capability. I other words, + TLS and DTLS are _not_ transports, because they build upon the TCP and UDP protocols, which + satisfy condition A. + + What the _location_ part consists of depends on what transport is identified. If the + transport is `tcp4` or `udp4`, the location is an IPv4 address expressed as four decimal + numbers separated by dots, a colon and a port number, such as in `192.168.3.22:64075`. If + the transport is `tcp6` or `udp6`, the location is an IPv6 address, rendered as described in + [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952), within square brackets, followed by a + colon and a port number. If the transport is `unix`, the location is an absolute filesystem + path to a Unix socket file. + type: string + pattern: ^(?[^:]+):\w*(?.*)$ + example: tcp4:192.168.0.7:45326 + + Error: + description: | + An indication of why a received request was rejected. It is formulated with the assumption + that the subject knows of and can interpret the status code in the response. + type: object + properties: + message: + description: A human-readable explanation of why the request was rejected. + type: string + + Triplet: + description: | + Three strings identifying a _subject_, an _operation_ and an _resource_, in that order. + Together they describe how a certain subject wishes do perform a certain operation on a + certain resource. + type: object + properties: + subject: + type: string + description: The identifier of the entity making the request. The format of the string is + dependant on the Authentication mechanism used. (e.g., a certificate string, token, id, etc) + access-right: + type: string + description: String identifier for the access right needed to be authorized. These access rights + must be pre-defined within the policy engine used. ("consume", "read", "write", "delete", "update", etc) + resource: + type: string + description: The identifier of the resource being accessed, e.g., service instance identifier. + required: + - subject + - access-right + - resource \ No newline at end of file diff --git a/5.0 Draft/IDD/IDDs Authorization System/eu.arrowhead.authorization-management-http-json.yml b/5.0 Draft/IDD/IDDs Authorization System/eu.arrowhead.authorization-management-http-json.yml new file mode 100644 index 0000000..6bb3576 --- /dev/null +++ b/5.0 Draft/IDD/IDDs Authorization System/eu.arrowhead.authorization-management-http-json.yml @@ -0,0 +1,582 @@ +openapi: 3.0.3 +info: + title: Authorization Policy Management API + description: | + This specification outlines how to realize the _Arrowhead Authorization Management_ service on top of either of the HTTP or HTTPS + protocols with payload encoded in JSON. The service allows for resources, data owners, service providers, or system administrators + to manage and express authorization rules to resources. + + Although the interface definition for the authorization system does not impose requirements on an implementation of that service + with regards to how it determines if certain subjects are allowed to perform certain access rights on certain resources. This interface + definition is designed to allow for Attribute-based Access Control to be enforced in the Authorization system. However, the same + definition can be used to describe and manage role-based or rule-based policies by the flexible use of associations and permissions. + + This interface understands _resources_ as the entities needing protection, e.g., services, data-bases, files, etc. On the other + hand, _subjects_ represents the entities trying to access or consume the previously defined _resources_. Finally, _access-rights_ + represents the actions that _subjects_ attempt to performed over the protected _resources_, these can be defined with different levels + of granularity, such as service consumption, or read or write of data. Moreover, this interface definition understands _attributes_ as + characteristics from users or resources to which policies can be defined. These properties describe the relevant entities and are mainly + of two types: User Attributes and Object Attributes. User attributes describe the entities trying to access resources. These can be + characteristics such as roles, clearance levels, job title, etc. Moreove, object attributes describe the properties of the resources being + accessed and protected. These properties can be such as data classifications, sensitivity levels, file type, location, source, etc. + As an example, one can set attributes to behave as roles, e.g., the user 'Alice' can be assigned to the 'IT staff' attribute, while the + devices 'TempSensor1' and 'TempSensor2' are both assigned to the 'Sensor data' attribute. If a policy connects the User Attribute 'IT staff' + with the object attribute 'Sensor data', then Alice will be able to consume data from both Temperature sensors. + + To express authorization policies over resources needing protection, a _resource_ object must be created in the policy engine. This + newly created resource can be _associated_ to existing attributes using the _/management/associations_ endpoint. The same applies + whenever a new _subject_ wanting to consume a _resource_ enters to the environment. A _subject_ object must be created in the policy + engine, and it needs to be connected to an attribute using the _/management/associations_ endpoint. This association will connect + the newly created _resource_ or _subject_ to existing authorization policies. + + Connections between _User Attributes_ and _Object Attributes_ are made through the creation of _permissions_ by using the + _/management/permissions_ endpoint. Creating a permission means that the _User Attribute_ get permission for the specified _access-rights_ + to be executed on the specified _resource attribute_. This means, for example, if a permission using the user attribute 'IT staff' with the + _access-rights_ + + + version: 1.0.0 + +paths: + /ping: + get: + summary: Endpoint to check the core system availability. + description: Returns an OK to indicate that the core system is available. + responses: + '200': + description: OK + + /management/associations: + post: + summary: Create a New association + description: Create a new association relating resources to resource-attributes, subjects to + subject attributes, or attribute-attribute associations. + The resource or subject must be an existing object. The specified attribute can be one existing from the + attributes collection, or if a non-existant attribute is specified, the new attribute will be created in + the collection. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Association' + examples: + example1: + summary: A call to associate a Temperature sensor service to the existing "OutsideTemp" resource attribute. + value: + id: "123123" + association-type: "resource" + target: + id: "existing-resource123" + name: "eu.arrowhead.tempreadings-http-json" + attribute: + id: "existing-attribute1233" + name: "OutsideTemp" + attribute-type: "resource" + responses: + '201': + description: Association created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Association' + get: + summary: List Associations + description: Retrieve a lizst of all associations. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Association' + headers: + Limit: + $ref: '#/components/headers/Limit' + + /management/associations/{associationId}: + get: + summary: Get Policy by ID + description: Retrieve details of a specific policy by its identifier. + parameters: + - name: associationId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Association' + put: + summary: Update Association + description: Update an existing Association by its identifier. + parameters: + - name: associationId + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Association' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Association' + delete: + summary: Delete Association + description: Delete an Association by its identifier. + parameters: + - name: associationId + in: path + required: true + schema: + type: string + responses: + '204': + description: No content + + /management/permissions: + post: + summary: Grant a new set of permissions. + description: Create a new set of permissions between a resource-attributes and a subject-attribute specified in the + request body. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Permission' + examples: + example1: + summary: A call to derive "consume" privileges for the subject attribute "TempController" to the + resource attribute "OutsideTemp". + value: + id: "321654" + subject-attribute: + id: "someid123" + name: "TempController" + attribute-type: "subject" + access-rights: + - "consume" + resource-attribute: + id: "existing-attribute1233" + name: "OutsideTemp" + attribute-type: "resource" + responses: + '201': + description: Permission created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/Permission' + + get: + summary: List Permissions + description: Retrieve a list of all Permissions. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Permission' + headers: + Limit: + $ref: '#/components/headers/Limit' + /management/permissions/{permissionId}: + get: + summary: Get permission by ID + description: Retrieve details of a specific permission by its identifier. + parameters: + - name: permissionId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Permission' + put: + summary: Update Permission + description: Update an existing permission by its identifier. + parameters: + - name: permissionId + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Permission' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Permission' + delete: + summary: Delete Permission + description: Delete a permission by its identifier. + parameters: + - name: permissionId + in: path + required: true + schema: + type: string + responses: + '204': + description: No content + + /management/subjects: + get: + summary: List subjects + description: Retrieve a list of all subjects. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Subject' + headers: + Limit: + $ref: '#/components/headers/Limit' + /management/subjects/{subjectId}: + get: + summary: Get Subject by ID + description: Retrieve details of a specific subject by its identifier. + parameters: + - name: subjectId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Subject' + delete: + summary: Delete subject + description: Delete a subject by its identifier. + parameters: + - name: subjectId + in: path + required: true + schema: + type: string + responses: + '204': + description: No content + /management/resources: + get: + summary: List resources + description: Retrieve a list of all resources. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Resource' + headers: + Limit: + $ref: '#/components/headers/Limit' + post: + summary: Create a new resource + description: Create a new resource to be the target of authorization rules. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Resource' + responses: + '201': + description: Resource created successfully + + /management/resources/{resourceId}: + get: + summary: Get resources by ID + description: Retrieve details of a specific resource by its identifier. + parameters: + - name: resourceId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Resource' + delete: + summary: Delete resource. + description: Delete a resource by its identifier. + parameters: + - name: resourceId + in: path + required: true + schema: + type: string + responses: + '204': + description: No content + + /management/user-attributes: + get: + summary: List user attributes + description: Retrieve a list of all user attributes. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Attribute' + headers: + Limit: + $ref: '#/components/headers/Limit' + /management/user-attributes/{uaId}: + get: + summary: Get user attribute by ID + description: Retrieve details of a specific user attribute by its identifier. + parameters: + - name: uaId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Attribute' + delete: + summary: Delete user attribute. + description: Delete an user attribute by its identifier. + parameters: + - name: uaId + in: path + required: true + schema: + type: string + responses: + '204': + description: No content + /management/object-attributes: + get: + summary: List object attributes + description: Retrieve a list of all object attributes. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Attribute' + headers: + Limit: + $ref: '#/components/headers/Limit' + /management/object-attributes/{oaId}: + get: + summary: Get user object by ID + description: Retrieve details of a specific object attribute by its identifier. + parameters: + - name: oaId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Attribute' + delete: + summary: Delete object attribute. + description: Delete an object attribute by its identifier. + parameters: + - name: oaId + in: path + required: true + schema: + type: string + responses: + '204': + description: No content + + +components: + headers: + Limit: + description: | + An indication of the maximum number of records the consuming system is allowed to have + included in the response to its query. + schema: + type: number + format: int32 + minimum: 0 + required: true + + schemas: + + Association: + oneOf: + - $ref: "#/components/schemas/ResourceAttributeAssociation" + - $ref: "#/components/schemas/SubjectAttributeAssociation" + - $ref: "#/components/schemas/AttributeAttributeAssociation" + + ResourceAttributeAssociation: + type: object + properties: + resource: + $ref: '#/components/schemas/Resource' + attribute: + $ref: '#/components/schemas/Attribute' + required: + - resource + - attribute + + SubjectAttributeAssociation: + type: object + properties: + subject: + $ref: '#/components/schemas/Subject' + attribute: + $ref: '#/components/schemas/Attribute' + required: + - subject + - attribute + + AttributeAttributeAssociation: + type: object + properties: + attribute1: + $ref: '#/components/schemas/Attribute' + attribute2: + $ref: '#/components/schemas/Attribute' + required: + - attribute1 + - attribute2 + + Attribute: + type: object + required: + - id + - name + - Attribute-type + properties: + id: + type: string + description: The unique identifier of the attribute + name: + type: string + description: The human-readable name of the attribute + Attribute-type: + type: string + enum: ['user', 'object'] + description: Type of the Attribute, 'user' for subject attributes (or roles), 'object' for resource attributes. + metadata: { $ref: '#/components/schemas/Metadata' } + + Metadata: + description: | + Additional details of when creating a policy element. What metadata is made available + depends on the type of the service holding the metadata. Possible examples of metadata are + HTTP base paths, message size restrictions and caching directives. + type: object + example: {"basePath":"v2"} + + Subject: + type: object + required: + - id + - name + properties: + id: + type: string + description: The unique identifier of the subject + name: + type: string + description: The human-readable name of the subject + auth-info: + type: string + description: Authentication information in case needed. E.g., certificate information of consuming systems. + metadata: { $ref: '#/components/schemas/Metadata' } + + Permission: + type: object + properties: + id: + type: string + description: "Identifier of the permission" + subjectAttribute: + $ref: "#/components/schemas/Attribute" + accessRights: + type: array + items: + type: string + description: "Access rights, e.g., ['consume']" + description: "List of access rights" + resourceAttribute: + $ref: "#/components/schemas/Attribute" + required: + - id + - subjectAttribute + - accessRights + + Resource: + required: + - id + - name + type: object + properties: + id: + type: string + description: the unique identifier of the resource + name: + type: string + description: the human-readable name of the resource + auth-info: + type: string + description: Authentication information in case needed. E.g., certificate information of providing systems. + metadata: { $ref: '#/components/schemas/Metadata' } diff --git a/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-pull-http-json.yml b/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-pull-http-json.yml new file mode 100644 index 0000000..66ea46b --- /dev/null +++ b/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-pull-http-json.yml @@ -0,0 +1,181 @@ +openapi: 3.0.3 + +info: + title: Service Orchestration-pull service API description + description: | + An API for using the Service Orchestration-pull service of the Orchestration core system. This service uses the orchestration store policies + to recommend service providers to the requesting consumer to fulfil its task. + + The consumer system request for orchestration either by specifying the service definition that the consumer requires or by using stored SoS + configurations or Orchestration rules if no service information is defined. + + _SoS configurations_ represents the connections needed in a SoS for it to perform its designed task. This means, describing what services + must each of the systems consume to perform their individual tasks. A SoS configuration can be seen as a series of _Orchestration rules_. + _Orchestration rules_ represents a desired interaction between systems consuming specific services from specific preferred providers. + + In the context of this document, we reffer to the Orchestration consumer as _requesting-system_ where _system-id_ is the + unique identifier that represents that system. The _requested-service_ represents the service information that the _requesting-system_ + requires orchestration. In case the _requested_service_ is specified, the requires service definition must be included in the form, + The orchestration system will attempt to match the _requested-service_ information with services present on the orchestration rules or SoS + configurations. + + version: 5.0.0-rc.1 + +paths: + /orchestration/echo: + get: + summary: Endpoint to check the core system availability. + description: Returns an OK to indicate that the core system is available. + responses: + '200': + description: OK + + + /orchestration/service-recommendations: + post: + summary: Submit a service request and get orchestration response. If no service definition is specified, the orchestration + will return the suggested services and their appropriate providers for the consuming system to fulfil its tasks, depending + on a existing SoS configuration or Orchestration rules. + + Information of the requesting system is mandatory. Requested service is optional. If a requested service object is specified, + the service definition must be specified. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceRequestForm' + responses: + '200': + description: Successful orchestration response. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/OrchestrationResponse' + + /orchestration/service-recommendations/{id}: + get: + summary: Get complete Orchestration plan for a given system, queried by system id + parameters: + - name: id + in: path + required: true + description: ID of requesting system + schema: + type: string + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/OrchestrationResponse' + '404': + description: System id not found + content: + application/json: + example: + error: Orchestration failed, system id not found. + + +components: + schemas: + + Auth-tokens: + description: | + An (k,v) object containing authorization tokens required to consume orchestration services + type: object + example: {"interfaceName1":"token1"} + + Metadata: + description: | + Additional details of relevance when consuming a service. What metadata is made available + depends on the type of the service holding the metadata. Possible examples of metadata are + HTTP base paths, message size restrictions and caching directives. + type: object + example: {"basePath":"v2"} + + RequestedService: + type: object + description: | + Optional information of the required service. This object contains the service requirements of the requester + system. + properties: + service-definition: + type: string + description: Service definition string identifier + service-type: + type: string + description: Service type string identifier + version: + $ref: '#/components/schemas/VersionReq' + required: + - service-definition + + ServiceInstance: + type: object + properties: + id: + type: string + description: service instance unique identifier, the consumer getting the response use this to query the service registry to get + full service information and connection address. + + ServiceRequestForm: + type: object + properties: + auth-tokens: + description: Authentication token of the requesting system + $ref: '#/components/schemas/Auth-tokens' + requesting-system: + type: string + description: Requesting system unique identifier + requested-service: + $ref: '#/components/schemas/RequestedService' + + OrchestrationResponse: + type: object + properties: + services: + type: array + items: + $ref: '#/components/schemas/ServiceInstance' + warnings: + type: array + items: + $ref: '#/components/schemas/Warning' + + Version: + description: | + A MAJOR, MINOR and a PATCH number, separated by dots. If both or the latter of the MINOR and + PATCH numbers are omitted, the ones omitted are assumed to be zero. + type: string + pattern: ^\d+(?:\.\d+(?:\.\d+)?)?$ + example: 1.4 + + VersionReq: + description: | + Object describing the required service version, maximun version and minimun version allowed for the + required service. + type: object + properties: + version-required: + $ref: '#/components/schemas/Version' + min-version: + $ref: '#/components/schemas/Version' + max-version: + $ref: '#/components/schemas/Version' + + Warning: + description: A JSON object containing string warnings that may be returned as part of an orchestration response. + FROM_OTHER_CLOUD -> if the provider is in another cloud to that of the requesting system + TTL_EXPIRED -> if the provider is no longer accessible + TTL_EXPIRING -> the provider will be inaccessible within a short time + TTL_UNKNOWN - > the provider does not especify an expiration time + type: string + enum: + - FROM_OTHER_CLOUD + - TTL_EXPIRED + - TTL_EXPIRING + - TTL_UNKNOWN \ No newline at end of file diff --git a/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-push.yml b/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-push.yml new file mode 100644 index 0000000..047c298 --- /dev/null +++ b/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-push.yml @@ -0,0 +1,139 @@ +asyncapi: 2.0.0 +info: + title: Service Orchestration-push Service + description: | + The Service Orchestration-push service allows for systems to load System of systems (SoS) configurations into another systems. + This allows to load service consumption directives remotely into systems to perform a task. + + If no configuration is specified in the triggering message, the active configuration on the orchestrator will be pushed + into the target system. SoS Configurations are expressed as a series of orchestration rules, and represent desired SoS states + for specific tasks. + + An _orchestration rule_ connects a specified _provider_ providing a _service_ with a _consumer_. This means that the + _consumer_ is adviced to consume the _service_, prefferably from the listed _provider_. Additional matching metadata + can be specified as part of the orchestration rule. + +version: 5.0.0-rc.1 + +channels: + pushConfiguration: + address: 'orchestration/push' + publish: + message: + $ref: "#/components/messages/SystemConfigurationEvent" + bindings: + amqp: + # Specify AMQP-specific details here if using AMQP + mqtt: + # Specify MQTT-specific details here if using MQTT + http: + # Specify HTTP-specific details here if using HTTP + + +components: + schemas: + Address: + description: | + Identifies a _transport_ and a _location_. + + The _transport_ identifies the base protocol that facilitates addressing a specific service + instance. Examples of transports that can be supported are `tcp4`, `tcp6`, `udp4`, `udp6` + and `unix`. A protocol only counts as a transport if it both (A) provides a way of + addressing and, by extension, sending messages to service providers and consumers, as well + as (B) does not build upon another protocol also providing this capability. I other words, + TLS and DTLS are _not_ transports, because they build upon the TCP and UDP protocols, which + satisfy condition A. + + What the _location_ part consists of depends on what transport is identified. If the + transport is `tcp4` or `udp4`, the location is an IPv4 address expressed as four decimal + numbers separated by dots, a colon and a port number, such as in `192.168.3.22:64075`. If + the transport is `tcp6` or `udp6`, the location is an IPv6 address, rendered as described in + [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952), within square brackets, followed by a + colon and a port number. If the transport is `unix`, the location is an absolute filesystem + path to a Unix socket file. + type: string + pattern: ^(?[^:]+):\w*(?.*)$ + example: tcp4:192.168.0.7:45326 + + Configuration: + type: object + properties: + configId: + type: string + description: unique identifier of the SoS configuration + name: + type: string + description: configuration human readable name + rules: + type: array + description: set of rules that compose the configuration + items: + $ref: '#/components/schemas/Rule' + target: + type: array + description: Target of the orchestration configuration + items: + $ref: '#/components/schemas/System' + + Metadata: + description: | + Additional details of relevance when consuming a service. What metadata is made available + depends on the type of the service holding the metadata. Possible examples of metadata are + HTTP base paths, message size restrictions and caching directives. + type: object + example: {"basePath":"v2"} + + Rule: + type: object + properties: + ruleId: + type: string + provider: + $ref: '#/components/schemas/System' + consumer: + $ref: '#/components/schemas/System' + service: + $ref: '#/components/schemas/Service' + Metadata: + $ref: '#/components/schemas/Metadata' + + Service: + type: object + description: Information about the orchestrated service + properties: + serviceID: + type: string + description: identifier of service + serviceInstance: + type: string + description: name of the service instance + + System: + type: object + description: information describing a system within a local cloud. + properties: + system-name: + type: string + description: human readable name of the system + address: + $ref: '#/components/schemas/Address' + + TimeToLive: + description: TTL, duration specigying the maximun amount of time a service regristration remains valid before requiring renewal or + expiration. + type: string + pattern: ^(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$ + example: 2d12h + + + messages: + SystemConfigurationEvent: + summary: Event triggered to push system configurations to a target system + payload: + type: object + properties: + systemId: + type: string + description: Identifier of the system for which configuration is pushed + configuration: + $ref: '#/components/schemas/Configuration' diff --git a/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-store-management-http-json.yml b/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-store-management-http-json.yml new file mode 100644 index 0000000..2ef641f --- /dev/null +++ b/5.0 Draft/IDD/IDDs Orchestration System/eu.arrowhead.orchestration-store-management-http-json.yml @@ -0,0 +1,260 @@ +openapi: 3.0.3 +info: + title: Orchestration Management API + description: | + This API defines interfaces to interact with the Orchestration store where Orchestration rules and Sos configurations + are stored. + + An _orchestration rule_ connects a specified _provider_ providing a _service_ with a _consumer_. This means that the + _consumer_ is adviced to consume the _service_, prefferably from the listed _provider_. Additional matching metadata + can be specified as part of the orchestration rule. + + The orchestration store has also the capability of storing system of systems (SoS) configurations. These configurations + are expressed as a series of orchestration rules, and represent desired SoS states for specific tasks. Configurations can + be stored and retrieved using the described interfaces in this document. Moreover, active configurations for a local cloud + can be defined using the _active-configuration_ endpoint. The active configuration is used by the orchestration to + provide orchestration responses to consumers. + + When setting active configurations, a time-to-live parameter can be defined to specify for how long the specific configuration + is valid in the local cloud. + version: 5.0.0-rc.1 + + +paths: + /orchestration/rules: + get: + summary: Get All Orchestration Rules + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Rule' + post: + summary: Create Orchestration Rule + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + responses: + '201': + description: Orchestration Rule created successfully + '400': + description: Invalid request + + /orchestration/rules/{ruleId}: + get: + summary: Get Orchestration Rule by ID + parameters: + - name: ruleId + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + '404': + description: Orchestration Rule not found + + put: + summary: Update Orchestration Rule + parameters: + - name: ruleId + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Rule' + responses: + '200': + description: Orchestration Rule updated successfully + '404': + description: Orchestration Rule not found + '400': + description: Invalid request + + delete: + summary: Delete Orchestration Rule + parameters: + - name: ruleId + in: path + required: true + schema: + type: string + responses: + '204': + description: Orchestration Rule deleted successfully + '404': + description: Orchestration Rule not found + + /orchestration/configurations: + post: + summary: Upload System of Systems Configuration + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + responses: + '201': + description: Configuration uploaded successfully + '400': + description: Invalid request + + get: + summary: Get Orchestration Configurations + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Configuration' + + /orchestration/configurations/{id}: + delete: + summary: Delete Configuration + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '204': + description: Configuration deleted successfully + '404': + description: Configuration not found + + /orchestration/configurations/active-configuration: + get: + summary: Get Active Configuration + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ActiveConfiguration' + + put: + summary: Set Active Configuration + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ActiveConfiguration' + responses: + '200': + description: Active Configuration set successfully + '400': + description: Invalid request + +components: + schemas: + ActiveConfiguration: + type: object + properties: + configuration: + $ref: '#/components/schemas/Configuration' + validity: + $ref: '#/components/schemas/TimeToLive' + + Configuration: + type: object + properties: + configId: + type: string + description: unique identifier of the SoS configuration + name: + type: string + description: configuration human readable name + rules: + type: array + description: set of rules that compose the configuration + items: + $ref: '#/components/schemas/Rule' + + Metadata: + description: | + Additional details of relevance when consuming a service. What metadata is made available + depends on the type of the service holding the metadata. Possible examples of metadata are + HTTP base paths, message size restrictions and caching directives. + type: object + example: {"basePath":"v2"} + + Rule: + type: object + properties: + ruleId: + type: string + provider: + $ref: '#/components/schemas/System' + consumer: + $ref: '#/components/schemas/System' + service: + $ref: '#/components/schemas/Service' + Metadata: + $ref: '#/components/schemas/Metadata' + + Service: + type: object + description: Information about the orchestrated service + properties: + serviceID: + type: string + description: identifier of service + serviceDefinition: + type: string + description: name of the service instance + serviceType: + type: string + description: name of the service type + version: + $ref: '#/components/schemas/Version' + + System: + type: object + description: information describing a system within a local cloud. + properties: + system-name: + type: string + description: human readable name of the system + + TimeToLive: + description: TTL, duration specigying the maximun amount of time a service regristration remains valid before requiring renewal or + expiration. + type: string + pattern: ^(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$ + example: 2d12h + + Version: + description: | + A MAJOR, MINOR and a PATCH number, separated by dots. If both or the latter of the MINOR and + PATCH numbers are omitted, the ones omitted are assumed to be zero. + type: string + pattern: ^\d+(?:\.\d+(?:\.\d+)?)?$ + example: 1.4 \ No newline at end of file diff --git a/5.0 Draft/IDD/IDDs Service Registry/eu.arrowhead.service-discovery-http-json.yml b/5.0 Draft/IDD/IDDs Service Registry/eu.arrowhead.service-discovery-http-json.yml new file mode 100644 index 0000000..e28d8d5 --- /dev/null +++ b/5.0 Draft/IDD/IDDs Service Registry/eu.arrowhead.service-discovery-http-json.yml @@ -0,0 +1,750 @@ +openapi: 3.0.3 + +info: + title: Service Discovery HTTP(S)-JSON + description: | + This specification outlines how to realize the _Arrowhead Core Service Discovery_ service on + top of either of the HTTP or HTTPS protocols with payloads encoded in JSON. The service allows + for consumers to register, deregister and search for _service records_, provided by themselves + or by other service providers. + + Each service record represents a currently provided service and contains all details necessary + to _contact_ that service. Such details will always include network addresses and a _service_ + _type identifier_, apart from other optional information. The service type identifier is a + reference to the particular message protocol implemented by the provided service. Such a + protocol typically builds upon a base protocol, such as HTTP or MQTT, and includes endpoints, + topics or other operators, as well as message types specific to the provided service. For the + consumption of the service referred to by a service record to be possible, the consumer in + question must already implement the protocol referred to by its service type identifier. + + + ## Compression and Language + + An implementation of this service interface _may_ be designed to support compression and/or + human-readable error texts in different languages than English, as described in + [RFC 9110, Section 12](https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation). Not + using compression _must_ be supported and be the default. Also, the default language for error + messages _must_ be American English (`en-US`). + + ## Managing Record Life-Cycles + + In a typical use case, this service interface is meant to hold records for all service providers + currently part of its context. When a service provider joins or leaves a context, it is expected + to register and deregister its services, respectively. However, service providers can fail or be + detached from the context before they get a chance to deregister their services. This can make + it relevant to monitor service providers and temporarily suppress or permanently prune records + associated with unhealthy or inaccessible providers. Implementations of this service interface + are free to suppress and/or prune records in whatever way best supports the use cases they are + designed for. + + ## Record Ownership + + It is the provider indicated inside each record that is the owner of the record, and not the + consumer registering it. This means that a consumer may be forbidden from registering or + deregistering a record for certain or all other service providers, even if it may register + and/or deregister records with itself as provider. + + ## Provider Identifiers + + Every service instance registered via this service interface _must_ be associated with a unique + identifier. In contexts where authentication is not used, providers _must_ chose their own + identifiers. Those identifiers _should_ remain consistent between restarts of those providers. + + ## Size Limits + + As a mitigation against denial-of-service attacks, all implementations of this service + interface _should_ reject incoming requests that are larger than a predefined limit. That limit + _must not_ be smaller than 8192 bytes for each received request. An implementation _may_ also + limit the sizes of individual parts within each request. It _must_, however, receive request + URI:s up to 2816 bytes in size, as well as request payloads up to 4096 bytes in size. + version: 5.0.0-rc.1 + +paths: + + /echo: + get: + summary: Endpoint to check the core system availability. + description: Returns an OK to indicate that the core system is available. + responses: + '204': + description: OK + + /services: + + get: + operationId: list + description: | + Lists the services registered in the service registry. Each service is returned with its + registered information, containing information on how to reach each service instance. + + As a default, only 16 services will be returned in the list request. This can be changed + by using the list-size parameter. + + Moreover, a service Query object can be included in the request. This service query refines + the list results to include only those services that satisfy the requirements specified in the + Service Query object. + + parameters: + - $ref: '#/components/parameters/query-offset' + - $ref: '#/components/parameters/serviceQueryParam' + - $ref: '#/components/parameters/list-size' + responses: + '200': + description: Matching service records. + content: + application/json: + schema: + $ref: '#/components/schemas/Records' + headers: + Cache-Control: + $ref: '#/components/headers/Cache-Control' + Limit: + $ref: '#/components/headers/Limit' + '400': { $ref: '#/components/responses/400-BadRequest-ExpressionIsInvalid' } + '401': { $ref: '#/components/responses/401-Unauthorized' } + '403': { $ref: '#/components/responses/403-Forbidden' } + '408': { $ref: '#/components/responses/408-RequestTimeout' } + '414': { $ref: '#/components/responses/414-URITooLarge' } + '415': { $ref: '#/components/responses/415-UnsupportedMediaType' } + '429': { $ref: '#/components/responses/429-TooManyRequests' } + '431': { $ref: '#/components/responses/431-RequestHeaderFieldsTooLarge' } + '500': { $ref: '#/components/responses/500-InternalServerError' } + '503': { $ref: '#/components/responses/503-ServiceUnavailable' } + + /services/register: + post: + summary: Add a new service entry + description: | + Registers one or more records. + + The combination of the provider and type identifiers inside each record must be unique. + If more than one record with corresponding identifiers are in the request, the last one + in its payload will replace all others. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Records' + + responses: + '204': + description: Confirms that the records in question have been registered. + '400': { $ref: '#/components/responses/400-BadRequest-RecordIsInvalid' } + '401': { $ref: '#/components/responses/401-Unauthorized' } + '403': { $ref: '#/components/responses/403-Forbidden' } + '406': { $ref: '#/components/responses/406-NotAcceptable' } + '408': { $ref: '#/components/responses/408-RequestTimeout' } + '411': { $ref: '#/components/responses/411-LengthRequired' } + '413': { $ref: '#/components/responses/413-PayloadTooLarge' } + '431': { $ref: '#/components/responses/431-RequestHeaderFieldsTooLarge' } + '500': { $ref: '#/components/responses/500-InternalServerError' } + '503': { $ref: '#/components/responses/503-ServiceUnavailable' } + + /services/{service-id}: + get: + summary: get service by ID + description: Retrieve details of a specific service entry by its identifier. + parameters: + - name: service-id + in: path + required: true + schema: + type: string + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Record' + + delete: + operationId: deregister + description: | + Deregisters the service matching the service-id. + + parameters: + - name: service-id + in: path + required: true + schema: + type: string + responses: + '204': + description: Confirms that the record in question have been deregistered. + '400': { $ref: '#/components/responses/400-BadRequest-ExpressionIsInvalid' } + '401': { $ref: '#/components/responses/401-Unauthorized' } + '403': { $ref: '#/components/responses/403-Forbidden' } + '408': { $ref: '#/components/responses/408-RequestTimeout' } + '414': { $ref: '#/components/responses/414-URITooLarge' } + '429': { $ref: '#/components/responses/429-TooManyRequests' } + '431': { $ref: '#/components/responses/431-RequestHeaderFieldsTooLarge' } + '500': { $ref: '#/components/responses/500-InternalServerError' } + '503': { $ref: '#/components/responses/503-ServiceUnavailable' } + +components: + + headers: + + Cache-Control: + description: | + If present, the value of this header may only include the `max-age`, `must-revalidate` and + `no-store` response directives, all of which are defined in + [RFC 9111 Section 5.2.2](https://datatracker.ietf.org/doc/html/rfc9111#name-response-directives). + + The `max-age` directive indicates for how many seconds the records in the response should be + cached before being queried again by the consumer. The `must-revalidate` directive is used + to forbid the consumer from using the records after the `max-age` has expired and the + attempt to fetch them again failed. The `no-store` directive instructs the consumer not to + cache the records at all. + schema: + type: string + example: max-age=1800, must-revalidate + required: false + + Limit: + description: | + An indication of the maximum number of records the consuming system is allowed to have + included in the response to its query. + schema: + type: number + format: int32 + minimum: 0 + required: true + + Retry-After: + description: | + An indication, in seconds, of how long a consumer is to wait before attempting the failed + request again. + schema: + type: number + format: int32 + minimum: 1 + required: true + + parameters: + + deregister-q: + name: q + in: query + description: | + Deregistration query, consisting of an array of comma-separated deregistration expressions. + Every record matching any of the individual expressions will be deregistered, if the + consumer has the appropriate permissions. + example: eu.arrowhead.service-discovery-http-json,eu.arrowhead.authorization-http-json@MWtzOXIpaUEsOyEhc1NsTwo= + schema: + type: array + items: { $ref: '#/components/schemas/DeregisterExpression' } + explode: false + allowReserved: true + + list-size: + name: size + in: query + description: | + An indication of the maximum number of records a consuming system wants to have included in + the response to the list request. + example: 24 + schema: + description: | + Indicates a maximum number of records a consuming service wishes to have included in the + response to the list request. + type: number + format: int32 + default: 16 + minimum: 1 + + query-offset: + name: offset + in: query + description: | + An indication of the number of records to skip, in order from the first matched, in the + response to a query. + example: 128 + schema: + description: | + Indicates a number of records to skip before collecting records into the response to some + query. + type: number + format: int32 + minimum: 0 + + query-q: + name: q + in: query + description: | + Query, consisting of an array of comma-separated query expressions. Every record matching + any of the individual expressions will be included in the response, unless the number of + matching records exceeds any limit imposed by the providing system. + example: eu.arrowhead.service-discovery-http-json~1.7*4,eu.arrowhead.authorization-http-json*12 + schema: + type: array + items: { $ref: '#/components/schemas/QueryExpression' } + explode: false + allowReserved: true + + filter: + name: filterString + in: query + description: | + Filter expressions to refine the results from the list request to the service registry. A filter + string is composed by one or more filter expressions, which are composed of a parameter, a matching + operator, and a value. For example: + Equality & Inequality checks + == "" + != "" + + Scalar comparison + > "" + >= "" + < "" + <= "" + + Emptiness checks + is empty + is not empty + + Contains checks or Substring Matching + "" in + "" not in + contains "" + not contains "" + + Valid parameters can be: Version, Interface, Security, ServiceType, Address, Port, ServiceInstanceID, ServiceName. + + Multiple expressions can be used to compose a filter string. These expressions can be connected with Boolean operators + such as 'or', 'and', 'not'. The composition of filter strings allows for parenthesis grouping. + schema: + type: string + + serviceQueryParam: + name: serviceQuery + in: query + description: | + Service object with filtering requirements for service discovery. All parameters in the object are optional. + schema: + $ref: '#/components/schemas/ServiceQuery' + + responses: + + 400-BadRequest-ExpressionIsInvalid: + description: | + Invalid query parameter or parameters. + + The offending parameters is identified in the payload of the error response. + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorExpressionIsInvalid' } + + 400-BadRequest-RecordIsInvalid: + description: | + A submitted record is invalid. + + The offending field is identified in the payload of the error response. + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorRecordIsInvalid' } + + 401-Unauthorized: + description: | + Consumer not yet authorized. + + The kind of authorization required _may_ be named in the error reponse. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 403-Forbidden: + description: | + Consumer is authorized, but lacks permission. + + If a particular parameter is the cause of this error, it will be named in the payload of the + error response. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 406-NotAcceptable: + description: | + A request contains either of the `Accept`, `Accept-Encoding` or `Accept-Language` headers, + and they do not allow for the service provider to respond using `application/json` as + `Content-Type` or with an encoding or language that the service provider supports. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 408-RequestTimeout: + description: | + A request did not arrive in full within an arbitrary timeout decided by the provider of this + service interface. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 411-LengthRequired: + description: | + The `Content-Length` header is missing in the request. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 413-PayloadTooLarge: + description: | + The payload in the request exceeds the limit imposed by the service provider. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 414-URITooLarge: + description: | + The size of the request line in the request, which includes the HTTP version, method and + URI, exceeds the limit imposed by the service provider. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 415-UnsupportedMediaType: + description: | + The request includes a payload encoded using a `Content-Type` unsupported by the service + provider. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 429-TooManyRequests: + description: | + The consumer has sent too many request in a too short time span. The consumer is expected to + wait the amount of time indicated in the `Retry-After` header before trying again. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + headers: + Cache-Control: + $ref: '#/components/headers/Retry-After' + + 431-RequestHeaderFieldsTooLarge: + description: | + The headers section in the request exceeds the limit imposed by the service provider. This + response code may indicate that + + 1. either the name or value of a field is too large, + 2. the combination of name and value in a field is too large, or + 3. the complete header section is too large. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 500-InternalServerError: + description: | + The server encountered an unexpected condition that prevented it from fulfilling the + request. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + + 503-ServiceUnavailable: + description: | + The service provider is currently near its operating capacity or is undergoing maintenance. + The consumer is expected to wait before trying again, as indicated by the `Retry-After` + header in the response. + content: + application/json: + schema: { $ref: '#/components/schemas/Error' } + headers: + Cache-Control: + $ref: '#/components/headers/Retry-After' + + schemas: + + Address: + description: | + Identifies a _transport_ and a _location_. + + The _transport_ identifies the base protocol that facilitates addressing a specific service + instance. Examples of transports that can be supported are `tcp4`, `tcp6`, `udp4`, `udp6` + and `unix`. A protocol only counts as a transport if it both (A) provides a way of + addressing and, by extension, sending messages to service providers and consumers, as well + as (B) does not build upon another protocol also providing this capability. I other words, + TLS and DTLS are _not_ transports, because they build upon the TCP and UDP protocols, which + satisfy condition A. + + What the _location_ part consists of depends on what transport is identified. If the + transport is `tcp4` or `udp4`, the location is an IPv4 address expressed as four decimal + numbers separated by dots, a colon and a port number, such as in `192.168.3.22:64075`. If + the transport is `tcp6` or `udp6`, the location is an IPv6 address, rendered as described in + [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952), within square brackets, followed by a + colon and a port number. If the transport is `unix`, the location is an absolute filesystem + path to a Unix socket file. + type: string + pattern: ^(?[^:]+):\w*(?.*)$ + example: tcp4:192.168.0.7:45326 + + DeregisterExpression: + description: | + An expression of facts about a set of service records to deregister. A deregister expression + consists of two parts, a _service part_ and a _provider part_. At least one of the two must + be part of the query, or it will always match zero records. + + The parts are identical to those with the same names part of the `QueryExpression`. Please + refer to its documentation for more details about their structure. + type: string + pattern: ^(?:(?[^!*,:@^~]+)(?:~(?\d+(?:\.\d+(?:\.\d+)?)?))?)?(?:@(?[A-Za-z0-9-_]*={0,2}))?$ + example: se.arrowhead.service-discovery-http-json@MWtzOXIpaUEsOyEhc1NsTwo= + + Error: + description: | + An indication of why a received request was rejected. It is formulated with the assumption + that the consumer knows of and can interpret the status code in the response. + type: object + properties: + message: + description: A human-readable explanation of why the request was rejected. + type: string + + ErrorExpressionIsInvalid: + description: | + Indicates how a search expression, part of a query or deregistration attempt, is invalid. + allOf: + - $ref: '#/components/schemas/Error' + - type: object + properties: + expression: + description: | + Identifies the first invalid expression in the original request, as well as + providing an explanation for why it is invalid. + type: object + properties: + offset: + description: | + The position of the offending expression, from the first given in the URI of the + rejected request. + type: number + format: int32 + minimum: 0 + example: 2 + message: + description: A human-readable explanation of why this record is invalid. + type: string + example: "Unexpected character '=' at position 20 of 'eu.arrowhead.service=registry'." + + ErrorRecordIsInvalid: + description: | + Indicates how a record, provided as part of a registration attempt, is invalid. + allOf: + - $ref: '#/components/schemas/Error' + - type: object + properties: + record: + description: | + Identifies the first invalid record in the original request, as well as providing + an explanation for why it is invalid. + type: object + properties: + offset: + description: | + The position of the offending record, from the first given in the rejected + request. + type: number + format: int32 + minimum: 0 + example: 4 + message: + description: A human-readable explanation of why this record is invalid. + type: string + example: "Required property missing: 'interfaces'." + + Interface: + description: An object describing interfaces used by services. This object contains information on the used + protocol and the security requirements. Depending on the protocol, additional properties could be appropriate, + such as 'version', 'contentTypes', 'ipv4Address', 'port', 'x509PublicKey', 'basePath' or 'topic'. The same + applying to security. + type: object + properties: + protocol: + type: object + properties: + name: + type: string + description: "Transport protocol, such as 'https', 'coaps+tcp', 'json-rpc', or 'mqtt'" + additionalProperties: true + required: + - name + security: + type: array + items: + type: object + properties: + name: + type: string + description: "Security method name, such as 'tokenAuthentication'" + additionalProperties: true + required: + - name + + Metadata: + description: | + Additional details of relevance when consuming a service. What metadata is made available + depends on the type of the service holding the metadata. Possible examples of metadata are + HTTP base paths, message size restrictions and caching directives. + type: object + example: {"basePath":"v2"} + + ProviderIdentifier: + description: | + An array of bytes identifying a particular service provider. The bytes are expressed using + the [URL safe Base 64 encoding](https://datatracker.ietf.org/doc/html/rfc4648#section-5). + type: string + pattern: ^[A-Za-z0-9-_]*={0,2}$ + example: MWtzOXIpaUEsOyEhc1NsTwo= + + QueryExpression: + description: | + An expression of facts about a desired set of service records. A query expression consists + of three parts, a _service part_, a _provider part_ and a _limit part_. At least one of the + two former parts must be part of the query, or it will always match zero records. + + The __service part__ must at least name a specific service type, but may also include a + version specifier. If given, the version specifier will match records with any other version + that is _compatible_ with it. A version specifier consist of a MAJOR, MINOR and a PATCH + number, separated by dots. If both or the latter of the MINOR and PATCH numbers are omitted + from a given version, the ones omitted are assumed to be zero. A given version is compatible + with a _candidate_ version if their MAJOR numbers are equal and the MINOR number of the + candidate version is greater than that of the given version. They are also compatible if + their MAJOR and MINOR numbers are equal and the PATCH number of the candidate version is + equal to or greater than that of the given version. For example, the query expression + `my-service~1.4` matches `my-service~1.4.1` and `my-service~1.6.5`. But it does not match + `my-service~1.3.9` or `my-service~2.0.4`. + + The __provider part__ limits matches to records that refer to the identified service + provider. + + The __limit part__ sets a limit on how many matching records to include in the response. It + consists of an asterisk followed by a positive integer, as in `a-service~1.0*4`. + type: string + pattern: ^(?:(?[^!*,:@^~]+)(?:~(?\d+(?:\.\d+(?:\.\d+)?)?))?)?(?:@(?[A-Za-z0-9-_]*={0,2}))?(?:\*(?\d+))?$ + example: se.arrowhead.service-discovery-http-json~1.6@MWtzOXIpaUEsOyEhc1NsTwo= + + Service: + type: object + properties: + name: + type: string + description: Service instance human-readable name + serviceType: + $ref: '#/components/schemas/TypeIdentifier' + version: + $ref: '#/components/schemas/Version' + addresses: + description: + A collection of addresses, each with a unique tag name. The tag names _may_ be used to + help a service consumer chose the most appropriate address. The service consumer may, + however, simply try all of them in any order until it finds one that works. + type: object + additionalProperties: + $ref: '#/components/schemas/Address' + interface: + type: array + items: + $ref: '#/components/schemas/Interface' + authInfo: + type: string + description: Specifies the authentication method needed (if any) to consume this service, e.g., certificate, token, etc. + metadata: + $ref: '#/components/schemas/Metadata' + + ServiceQuery: + type: object + description: Object with properties needed to refine the list results from the service registry list operation. All parameters + in this object are optional. Version, Interface, Security, ServiceType, Address, Port, ServiceInstanceID, ServiceName. + properties: + serviceInstanceIDs: + type: array + items: + type: string + description: The list of service instances IDs required in the list results. + ServiceNames: + type: array + items: + type: string + description: The list of service names required in the list results + VersionReq: + description: Service version requirements + $ref: '#/components/schemas/VersionReq' + AddressReq: + description: Service address requirements + type: array + items: + $ref: '#/components/schemas/Address' + interfacesReq: + type: array + description: Interface requirement + items: + $ref: '#/components/schemas/Interface' + + Records: + type: array + description: Envelope for array of Results for service list response. + items: + $ref: '#/components/schemas/Record' + + Record: + type: object + properties: + serviceID: + type: string + description: The unique identifier of the service entry. + providerID: + $ref: '#/components/schemas/ProviderIdentifier' + description: The ID of the system which produces the registered service. + service: + $ref: '#/components/schemas/Service' + timeToLive: + $ref: '#/components/schemas/TimeToLive' + required: + - serviceID + - providerID + - service + + interface: + description: A string that describes the interface in Protocol-SecurityType-MimeType format. SecurityType can be either SECURE or + INSECURE. + type: string + pattern: ^([a-zA-Z0-9_-]+)-(SECURE|INSECURE)-([a-zA-Z0-9_-]+)$ + example: HTTP-SECURE-JSON + + TimeToLive: + description: TTL, duration specigying the maximun amount of time a service regristration remains valid before requiring renewal or + expiration. + type: string + pattern: ^(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$ + example: 2d12h + + TypeIdentifier: + description: | + Identifies a particular type of service, such as `eu.arrowhead.service-discovery-coap-cbor` + or `eu.arrowhead.orchestration-http-json`. + type: string + pattern: ^[^!*,:@^~]+$ + example: eu.arrowhead.authorization-http-json + + Version: + description: | + A MAJOR, MINOR and a PATCH number, separated by dots. If both or the latter of the MINOR and + PATCH numbers are omitted, the ones omitted are assumed to be zero. + type: string + pattern: ^\d+(?:\.\d+(?:\.\d+)?)?$ + example: 1.4 + + VersionReq: + description: | + Object describing the required service version, maximun version and minimun version allowed for the + required service. + type: object + properties: + version-required: + $ref: '#/components/schemas/Version' + min-version: + $ref: '#/components/schemas/Version' + max-version: + $ref: '#/components/schemas/Version' diff --git a/5.0 Draft/IDD/IDDs Service Registry/eu.arrowhead.service-registry-administration-http-json.yml b/5.0 Draft/IDD/IDDs Service Registry/eu.arrowhead.service-registry-administration-http-json.yml new file mode 100644 index 0000000..b7bfb69 --- /dev/null +++ b/5.0 Draft/IDD/IDDs Service Registry/eu.arrowhead.service-registry-administration-http-json.yml @@ -0,0 +1,227 @@ +openapi: 3.0.0 +info: + title: Service Registry Management API + description: | + This specification outlines how to use the _Arrowhead Service Registry Administration_ service + on top of either of the HTTP or HTTPS protocols with payloads encoded in JASON. The service allows for + service providers or cloud administrators to list, register, or unregister services from the service + registry catalog. To register a service, the service provider, a system administrator, or a supporting system + must fill a _ServiceEntry_ object with the details of the service and the service provider. Additional + inforation can be especified in the _metadata_ parameter. + + ## Compression and Language + + An implementation of this service interface _may_ be designed to support compression and/or + human-readable error texts in different languages than English, as described in + [RFC 9110, Section 12](https://www.rfc-editor.org/rfc/rfc9110#name-content-negotiation). Not + using compression _must_ be supported and be the default. Also, the default language for error + messages _must_ be American English (`en-US`). + + ## Managing Record Life-Cycles + + In a typical use case, this service interface is meant to hold records for all service providers + currently part of its context. When a service provider joins or leaves a context, it is expected + to register and deregister its services, respectively. However, service providers can fail or be + detached from the context before they get a chance to deregister their services. This can make + it relevant to monitor service providers and temporarily suppress or permanently prune records + associated with unhealthy or inaccessible providers. Implementations of this service interface + are free to suppress and/or prune records in whatever way best supports the use cases they are + designed for. + + ## Record Ownership + + It is the provider indicated inside each record that is the owner of the record, and not the + consumer registering it. This means that a consumer may be forbidden from registering or + deregistering a record for certain or all other service providers, even if it may register + and/or deregister records with itself as provider. + + ## Provider Identifiers + + Every service instance registered via this service interface _must_ be associated with a unique + identifier. In contexts where authentication is not used, providers _must_ chose their own + identifiers. Those identifiers _should_ remain consistent between restarts of those providers. + + ## Size Limits + + As a mitigation against denial-of-service attacks, all implementations of this service + interface _should_ reject incoming requests that are larger than a predefined limit. That limit + _must not_ be smaller than 8192 bytes for each received request. An implementation _may_ also + limit the sizes of individual parts within each request. It _must_, however, receive request + URI:s up to 2816 bytes in size, as well as request payloads up to 4096 bytes in size. + + version: 1.0.0 + +paths: + /service-registry/list: + get: + summary: List all service entries + description: Retrieve a list of all service entries in the service registry. + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/ServiceEntry' + /service-registry/modify: + put: + summary: Modify a service entry + description: Modify an existing service entry in the service registry. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceEntry' + responses: + '200': + description: Service entry modified successfully + '404': + description: Service entry not found + /service-registry/add: + post: + summary: Add a new service entry + description: Add a new service entry to the service registry. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceEntry' + responses: + '201': + description: Service entry added successfully + /service-registry/delete: + delete: + summary: Delete a service entry + description: Delete an existing service entry from the service registry. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceEntry' + responses: + '200': + description: Service entry deleted successfully + '404': + description: Service entry not found + +components: + schemas: + Address: + description: | + Identifies a _transport_ and a _location_. + + The _transport_ identifies the base protocol that facilitates addressing a specific service + instance. Examples of transports that can be supported are `tcp4`, `tcp6`, `udp4`, `udp6` + and `unix`. A protocol only counts as a transport if it both (A) provides a way of + addressing and, by extension, sending messages to service providers and consumers, as well + as (B) does not build upon another protocol also providing this capability. I other words, + TLS and DTLS are _not_ transports, because they build upon the TCP and UDP protocols, which + satisfy condition A. + + What the _location_ part consists of depends on what transport is identified. If the + transport is `tcp4` or `udp4`, the location is an IPv4 address expressed as four decimal + numbers separated by dots, a colon and a port number, such as in `192.168.3.22:64075`. If + the transport is `tcp6` or `udp6`, the location is an IPv6 address, rendered as described in + [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952), within square brackets, followed by a + colon and a port number. If the transport is `unix`, the location is an absolute filesystem + path to a Unix socket file. + type: string + pattern: ^(?[^:]+):\w*(?.*)$ + example: tcp4:192.168.0.7:45326 + + Metadata: + description: | + Additional details of relevance when consuming a service. What metadata is made available + depends on the type of the service holding the metadata. Possible examples of metadata are + HTTP base paths, message size restrictions and caching directives. + type: object + example: {"basePath":"v2"} + + ProviderIdentifier: + description: | + An array of bytes identifying a particular service provider. The bytes are expressed using + the [URL safe Base 64 encoding](https://datatracker.ietf.org/doc/html/rfc4648#section-5). + type: string + pattern: ^[A-Za-z0-9-_]*={0,2}$ + example: MWtzOXIpaUEsOyEhc1NsTwo= + + TypeIdentifier: + description: | + Identifies a particular type of service, such as `eu.arrowhead.service-discovery-coap-cbor` + or `eu.arrowhead.orchestration-http-json`. + type: string + pattern: ^[^!*,:@^~]+$ + example: eu.arrowhead.authorization-http-json + + Service: + type: object + properties: + name: + type: string + description: Service instance human-readable name + service-type: + $ref: '#/components/schemas/TypeIdentifier' + version: + $ref: '#/components/schemas/Version' + addresses: + description: + A collection of addresses, each with a unique tag name. The tag names _may_ be used to + help a service consumer chose the most appropriate address. The service consumer may, + however, simply try all of them in any order until it finds one that works. + type: object + additionalProperties: + $ref: '#/components/schemas/Address' + interface: + type: array + items: + $ref: '#/components/schemas/Interface' + auth-info: + type: string + description: Specifies the authentication method needed (if any) to consume this service, e.g., certificate, token, etc. + metadata: + $ref: '#/components/schemas/Metadata' + + ServiceEntry: + type: object + properties: + serviceID: + type: string + description: The unique identifier of the service entry. + providerID: + $ref: '#/components/schemas/ProviderIdentifier' + description: The ID of the system which produces the registered service. + service: + $ref: '#/components/schemas/Service' + time-to-live: + $ref: '#/components/schemas/TimeToLive' + required: + - serviceID + - providerID + - service + + TimeToLive: + description: TTL, duration specigying the maximun amount of time a service regristration remains valid before requiring renewal or + expiration. + type: string + pattern: ^(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$ + example: 2d12h + + Interface: + description: A string that describes the interface in Protocol-SecurityType-MimeType format. SecurityType can be either SECURE or + INSECURE. + type: string + pattern: ^([a-zA-Z0-9_-]+)-(SECURE|INSECURE)-([a-zA-Z0-9_-]+)$ + example: HTTP-SECURE-JSON + + Version: + description: | + A MAJOR, MINOR and a PATCH number, separated by dots. If both or the latter of the MINOR and + PATCH numbers are omitted, the ones omitted are assumed to be zero. + type: string + pattern: ^\d+(?:\.\d+(?:\.\d+)?)?$ + example: 1.4 \ No newline at end of file