One of the main functions of the tdx Volt is the storage of resource metadata.
Almost all the entities exposed by the various tdx Volt APIs are represented internally by a resource in the metadata store, including identities, files, folders, databases, wires, 3rd party services and so on.
The metadata store is implemented as an SqlCipher database, a secure, encrypted-at-rest version of Sqlite.
Full details of the resource schema can be found in the protobuf definition
Resources are classified using a simple text-based, free-form taxonomy, represented by the
This is implemented as an ordered list of strings, where each entry in the list describes a ‘kind’.
There is a limited set of reserved kinds for use by the system.
All resources must have a top-level ‘kind’ that matches one of the reserved system ‘kinds’.
Most of the reserved ‘kinds’ are self-explanatory. They are listed in the table below.
|tdx:cloud-connection||Represents a connection to a cloud-based tunnel.|
|tdx:group||A group of identities.|
|tdx:home-folder||The home folder of a given identity.|
|tdx:http-proxy||An HTTP forward proxy resource.|
|tdx:http-server||An HTTP server resource.|
|tdx:identity||An identity resource.|
|tdx:service||The top-level service kind.|
|tdx:sqlite-database||A sub-kind of Database, representing an Sqlite database.|
|tdx:symbolic-link||A file or folder that is linked directly to the local file system.|
|tdx:volt-link||Used by the fusebox to store links to other Volts|
|tdx:web-view||Used by the fusebox to display web pages. Experimental, macOS only.|
|tdx:wire||A wire resource.|
A resource can reflect multiple ‘kinds’, for example:
- An SQLite database is represented by
- When a new identity is created in a Volt, the underlying resource is classified using the ‘kinds’
tdx:identity, tdx:folder, tdx:home-folder.
Clients can augment the default resource ‘kind’ with custom kinds that suit their domain, but they must not use the
tdx: prefix. For example
It is anticipated that the
kind property of a resource will often reflect a ‘type’ hierarchy along the lines of generic -> specific, but this isn’t enforced in any way and there will be use cases where this is not applicable.
The service description of a resource describes a grpc server, and is only applicable to resources that expose a grpc server.
A single grpc server can expose multiple services, where each service is described by the protobuf definition language.
All resources that expose a grpc server have the `tdx:service` kind.
Within the Volt, each resource is hosted by one and only one grpc server.
All built-in resources are hosted by the tdx Volt itself, which exposes a single grpc server that implements the following APIs:
If a client registers a service with the Volt, the details of where the service is running and the APIs it supports are supplied by the client as part of the registration process.
service_api field within the resource can be useful to discover services that expose a given interface. For example, the DiscoverServices API can be used to find all servers that expose the
To better illustrate this concept, consider the following:
- the tdx Volt exposes the
tdx.volt_api.data.v1.SqliteServerAPI, among others.
- when a database is created via the fusebox, a ‘use tdx Volt database server’ checkbox can be used to indicate if the database should be hosted by the tdx Volt or if the fusebox should try and discover other services that support the
- selecting ‘use tdx Volt database server’ means that any operations on that database are handled by the tdx Volt grpc server
- however, the SQLite Server utility also exposes
- when the Sqlite Server utility connects to the tdx Volt it registers it’s server with the Volt
- if a database is then created with ‘use tdx Volt database server’ not selected, the fusebox will ask the Sqlite Server utility to create the database
- any operations on that database are handled by the utility and not the Volt. If the Sqlite Server utility is not online then it will not be possible to interact with that database resource.
The resource schema is fixed as described by the protobuf definition.
However, clients can use the
attributes field of the resource to associate an arbitrary number of ResourceAttributes with any given resource.
A resource attribute is an advanced form of name-value pair. Each attribute is identified by a unique identifier and is of a specified data type. A single attribute instance can take multiple values.
For example, http proxy forwarder resources will have the following attributes attached when they are created via the fusebox:
|Attribute Id||Data Type||Description||Example|
|tdx:http-proxy-domain||string||The sub-domain to proxy on.||“docs”|
|tdx:http-proxy-host||string||The host to proxy to.||“localhost”|
|tdx:http-proxy-port||integer||The port to proxy to.||3000|
Clients can add attributes using identifiers that match their domain.
Attribute identifiers with the
tdx: prefix are reserved.
The GetResources API can be used to find resources based on the associated attributes.
Resource attributes are a good fit for the **tdx Volt** policy engine, which uses attribute-based rules rather than the traditional role-based approach. This means that policy rules can be defined for arbitrary attributes.
Each resource is assigned an owner at creation time, which by default is the currently authenticated identity that issued the command.
The resource owner can perform any operation on the resource.
By default the tdx Volt policy states that the Volt owner can also perform any operation on any resource, irrespective of the owner.
This differs from the standard TDX, which has no concept of an over-arching owner, and by default resources are only accessible to their owners. The **tdx Volt** operates in a peer-to-peer model. If Alice grants Bob permission to use her Volt, and Bob uploads some data to Alice's Volt, he does so in the knowledge that Alice has full access to that data. If Bob wanted to restrict the access Alice has to his data, he should create it on his own **tdx Volt** and invite Alice to connect, with the appropriate policy rules in place.
Resources can be organised hierarchically.
All resources are descended from the tdx Volt root resource.
When a client creates a resource, they indicate the parent resource that should contain the new resource. If a client does not specify a parent resource, the authenticated identity’s Home folder will be used.