Service Locator =============== The service locator model provides clients of trusted services with a common interface for locating service instances and establishing RPC sessions with service endpoints. By using the service locator, application code is decoupled from the details of where services are deployed. Use of the service locator is entirely optional for client applications. Different deployments of *libts* provide implementations of the service locator API that are suitable for different environments. The trusted services project uses *libts* to decouple test code from the services under test. This enables tests to be reused for testing on different platforms with different distributions of services. The same flexibility may be exploited when writing applications that use trusted services. Service Locator Model --------------------- The following class diagram illustrates the service locator model: .. uml:: uml/ServiceLocatorClassDiagram.puml The model takes inspiration from microservices architectures where there is a similar need to decouple clients from service location. In the model, classes have the following roles: Class service_locator ''''''''''''''''''''' The service_locator is responsible for locating service provider instances and returning a service_context object to allow a client to establish RPC sessions with the located service endpoint. A service instance is requested by a client using a service name. The service name uniquely identifies a service instance, independent of where the service provider is located. The service_locator is a singleton and forms the common interface for locating trusted services. Class service_context ''''''''''''''''''''' A service_context object represents a located service and enables a service client to establish RPC sessions with the service. A concrete service_context will provide open and close methods that manage RPC session setup and teardown. Class rpc_caller '''''''''''''''' An rpc_caller provides methods for making remote calls associated with a service endpoint. An rpc_caller object represents an instance of an RPC session. Locating Service Instances -------------------------- The location of service instances is likely to vary between deployments. Many factors influence where a service instance is deployed and the method needed to locate it. e.g.: - The type of processing environment in which a service instance is deployed. e.g. service could be deployed in a secure partition, as a TA or in a secure enclave. - Whether a service instance is co-located with other services instances in the same processing environment or whether a separate environment instance is used per service instance. - For Linux user-space clients, the kernel driver model used for messaging influences how a service is located and the type of messaging interface used for RPC requests. Because of the wide variability in service deployment options, the Trusted Services framework supports the following: - *Location independent service names* - a naming convention for identifying service instances, wherever they are located. By using a location independent service name, a client is decoupled from the actual location of a service instance (similar to a DNS names). A concrete service locator is responsible for resolving the location independent service name. - *Service location strategies* - to accommodate the likely variability, an extensible framework for alternative service location strategies is provided. Service Names ''''''''''''' Location Independent Service Names `````````````````````````````````` Because of the potential variability in where service instances are deployed, a naming convention that allows a service instance to be identified, independent of its location, is useful. By using a location independent service name, coupling between a client application and any particular service deployment can be avoided. Use of the Service Locator API and location independent service names allows client applications to be portable across different platforms. The service instance naming convention uses a URN type string to uniquely identify a particular instance of a class of service. To provide extensibility, a naming authority is included in the name. This allows anyone with a domain name to define their own unique service names. Core service names are defined under the *trustedfirmware.org* authority. The general structure of a service name is as follows:: urn:sn::.: The 'urn' prefix should be dropped when service names are used in context. The version field is optional. The naming convention includes a version number, separated from the field by a '.' character. Beyond the '.', any version numbering scheme may be used. This will potentially be useful for delegating version compatibility decisions to a service locator. It is preferable for a client to specify a service name that includes a version number as this will potentially allow a service locator to: - Locate a compatible service instance. For example, a service provider may expose multiple RPC call endpoints to handle different protocol versions. A service locator may resolve the name to the compatible RPC endpoint, based on the version string requested by the client. - Fail gracefully if no compatible version is found. Some example service names:: sn:trustedfirmware.org:crypto.1.0.4:0 sn:trustedfirmware.org:secure-storage.1.3.11:1 sn:trustedfirmware.org:tpm.2.0:0 Location Specific Service Names ``````````````````````````````` To enable a client to be able to specify location specific service names, it should also be possible to use names that express a location specific identifier such as a partition UUID. While use of location specific services names creates a coupling between the client and details of the service deployment, their use may be important in the following cases: - Where there is no well-known mapping between a location independent service name and a location specific identifier. - Where the client needs to be specific e.g. for tests that target a specific service deployment. Location specific service names use the same structure as location independent services names but with a technology specific authority field. The following is an example of a service name that identifies a service instance that is deployed in a secure partition:: sn:ffa:d9df52d5-16a2-4bb2-9aa4-d26d3b84e8c0:0 The instance field qualified a particular SP instance from the discovered set. Service Location Strategies ''''''''''''''''''''''''''' The method used by the service locator to resolve a service name to a service instance will depend on the environment in which a client is running and where service instances are located. Services will need to be located by any client of a trusted service. There are typically two classes of trusted service client: - A user-space application. - Another trusted service, running in a secure processing environment. Different methods for locating service instances in different environments are illustrated in the following examples: Locating a Service from Linux User-space ```````````````````````````````````````` Depending on the kernel driver model used, the example methods for locating service instances from Linux user-space are: 1. Service instances are represented by device nodes e.g. /dev/tpm0. The service locator will simply map the portion of the services name to the base device name and the to the device node instance. 2. A service instance is hosted by a TEE as a TA. The TEE will provide a discovery mechanism that will allow a TA type and instance to be identified. The service locator will need to map the service name to the TEE specific naming scheme. 3. A special device that provides messaging provides a method for discovery. e.g. an FF-A driver supports partition discovery. 4. A device is used for remote messaging to a separate microcontroller. There is a well-known protocol for endpoint discovery using the messaging layer. Locating a Service from another Trusted Service ``````````````````````````````````````````````` Where a trusted service uses another trusted service, it is likely that both service instances will be running in the same security domain e.g. both running in secure partitions within the secure world. Where a single service instance is deployed per secure partition, the client service will use the following strategy to locate the service provider: 1. The service name is mapped to the well known UUID for the class of SP that hosts the service provider. 2. FF-A partition discovery is used to find all SPs that match the requested UUID. 3. The service instance portion of the service name is used to match the partition ID when selecting the target SP from the list of discovered SPs. Extending the Service Locator Model ``````````````````````````````````` To accommodate the need to support alternative location strategies, the Service Locator model can be extended to use a set of concrete strategy objects to implement different methods of locating a service instance. The set of strategies used will be different for different client environments. The following class diagram illustrates how the model can be extended. .. uml:: uml/ServiceLocationStrategyClassDiagram.puml -------------- *Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.* SPDX-License-Identifier: BSD-3-Clause