Tornjak Open Source Project — Management Framework for Workload identities (“ZERO TRUST”)

Mohammed M. Abdi
Universal Workload Identity
8 min readMar 11, 2022

Nowadays most organizations are storing workloads in multiple cloud platforms, regions, and services. One of the reasons is the different sets of benefits each platform provides. Imagine managing an organization(s) worth of workloads placed in multiple platforms? Tornjak aims to solve this issue by providing a control plane with a user interface/ UI. This allows an organization(s) to simplify the identity workload management framework across deployments. Tornjak uses the SPIFFE/ SPIRE architecture to provide a “zero trust security architecture.”

Tornjak Logo
Figure 1: Tornjak Open-Source Project Under CNCF SPIFFE/ SPIRE Logo

SPIFFE, which stands for the “Secure Production Identity Framework For Everyone” provides a secure identity to every workload in a modern production environment. SPIRE stands for “SPIFFE Runtime Environment”, which manages platforms and workload attestation. Tornjak is built on top of SPIFFE/ SPIRE which allows the use of SPIRE plugins, such as attestation plugins, different cloud providers’ node attestors, and more.

SPIFEE and SPIRE Logo
Figure 2: SPIFFE and SPIRE Logo

Tornjak can run in two modes: the “agent mode” where it is managing a single SPIRE server deployment and the “manager mode” where it can manage multiple SPIRE servers, and multiple trust domains in a single location. To have a high-level understanding of Tornjak and to get started, read this blog post by Brandon Lum (a Tornjak project contributor). One of the main challenges Tornjak aims to resolve includes, identity and access control challenges from hybrid multi-cloud deployments and resource sharing by providing management tools for workload identities across various organizations. The Tornjak project is now fully open source and is donated to the CNCF (“Cloud Native Computing Foundation”) community under SPIFFE/ SPIRE.

Code Structure of Tornjak [Back-End & Front-End]

Tornjak Back-End Code Structure
Figure 3: Tornjak Back-End Code Structure

Tornjak is composed of the Back-End written in Go language — which interacts directly with the local SPIRE server via socket file. It also uses a local SQL database to persist locally SPIRE-specific metadata + extensions. The Back-End is separated into an agent and a manager component as mentioned above. Each management framework is organized into APIs (api), commands (cmd), and package (pkg).

The “api” component hosts the APIs required to perform specific functions, such as retrieving metadata information of an agent, entry, server, or cluster. Some APIs such as agent and entry APIs are directly pulled from SPIFFE/ SPIRE architecture making use of already existing APIs. Other Tornjak APIs are created for unique Tornjak workload management functionality purposes, such as pulling server metadata information, registering workload selectors to agents, and creating and managing clusters. This will be discussed further in later parts of the blog.

The “cmd” component holds the commands for the following functionalities: the local database, the config file for the SPIRE server, the server address to run the Tornjak HTTP server, the certificate, and the key path for TLS/ mTLS. TLS (“Transport Layer Security”) is an encryption protocol that authenticates the server in a client-server connection and mTLS (“Mutual TLS”) ensures both sides of the parties authenticate each other by verifying they have the correct private keys before proceeding. The cmd component also hosts the functionality to enable TLS and mTLS authentication and command to retrieve server information of the SPIRE server where Tornjak resides.

The “pkg” component hosts the local SQLite database to store agents' metadata information, agent selector information, agent plugin information, clusters metadata information, and entry metadata information with the functionality of adding, deleting, and editing a new entry. There are three individual tables stored in the database. The first table stores the agents with their SPIFFE IDs and plugins. The second table stores the clusters with the name of the cluster, when the cluster was created, the domain name of the cluster, the platform type, and who manages the cluster. And the third table stores the agent-cluster relationship table specifying unique CLUSTER ID and SPIFFE ID for the relationship.

Tornjak Front-End Code Structure
Figure 4: Tornjak Front-End Code Structure

And the Front-End — which is built-in React+Redux framework hosts all the front-end UI components including the cluster management, agent management, entry management, Tornjak server information management, and the Tornjak dashboard management framework with their helper functions and state management infrastructure. The recent changes in Tornjak focus on adding functionality to the front-end UI and related components to the backend infrastructure. This blog will be focusing on these changes and additions.

Tornjak User Interface Recent Additions

Tornjak Cluster Management Interface

Clusters List tab with clusters and their metadata information with associated agents
Figure 5: Clusters List tab with clusters and their metadata information with associated agents

The idea of organizing agents/ nodes into clusters bears multiple benefits. For example, better management of workloads based on criterias the agents/ nodes share.

We have designed a Tornjak SPIRE-Server cluster management interface that allows for Tornjak-SPIRE users to be able to create new clusters and assign agents/ nodes. Agents/ Nodes are SPIRE unique identities, and the clusters are utilized to organize these agents/ nodes.

Create Cluster tab
Figure 6: Create Cluster tab

For example, agents/ nodes can be associated with clusters according to different criterias including who manages the cluster, a specific domain name associated with multiple nodes, specific workload attestor for agents such as Docker, Kubernetes, Unix, etc which is defined by cluster type. We also have the functionality of modifying various metadata specifications of clusters that are already created.

Edit Cluster Tab
Figure 7: Edit Cluster Tab

Tornjak Agents Management Interface

We have updated and added new features to the agents' dashboard such as assigning workload selectors for nodes which allows for tracking of plugins associated with agents running on the SPIRE server and agents [Figure 8]. Since there is no API for selector/s associated with an agent configuration, we added this option to allow the user to specify the workload attestor during creation or the option of adding it post-creation. Now a user should be able to define annotations of the workload selectors used per agent at or post creation time. This can then be used for visibility and recommendation of selectors during the creation of an entry/ entries. We have also added the ability of a user to delete or ban an agent or multiple agents in one sequence based upon of requirement [Figure 9].

Agents Workload Selector Selection Modal
Figure 8: Agents Workload Selector Selection Modal
Agents “Delete” and “Ban” feature
Figure 9: Agents “Delete” and “Ban” feature

Tornjak Entries Management Interface

The “Entry Creation Assist”, guides users in the creation of entries with context known from the SPIRE server configuration and APIs as well as user-provided information. We have updated and added new features to the entries dashboard such as creating workload entries with assisted entry creation to avoid the manual creation that was in place before. A user can select from a list of readily available parent ids associated with nodes/ agents to create an entry. Alternatively, a user can make use of the manual option to input a custom parent id. The SPIFFE ID of the entry is pre-populated from the parent id association as SPIFFE IDs can only belong to the specified trust domain.

Create New Entry Tab
Figure 10: Create New Entry Tab

The selectors are also pre-populated from the parent id selection associated with the agent. Each SPIRE server and its agents are configured with node and workload attestors. These attestors have a set of possible selectors that can be recommended based on the configuration of the agents. By automating and updating the selector entry, which is a property of a workload that SPIRE can verify before issuing identity, we are making recommendations based upon the server or node as selected by the user. And also allows the user to specify custom properties for the workload entry depending on the platform or architecture on which the workload’s application is running.

Create New Entry, custom “Parent ID” selection
Figure 11: Create New Entry, custom “Parent ID” selection

Tornjak ServerInfo

The Tornjak server information is designed for the user/ CISO (Chief Information Security Officer) to manage the server/s based on the server information such as trust domain of the server, plugins associated with the server such as the “DataStore”, “KeyManager”, “NodeAttestor”, “NodeResolver”, “Notifier”. The plugins are displayed in a colorful tag display for an easier visualization of server information. More information and metadata about the server can be found in the verbose config section below the plugins.

Tornjak Server Info Tab
Figure 12: Tornjak Server Info Tab

Tornjak Dashboard

We have designed the Tornjak Dashboard framework for an easier management of the entities or constructs such as clusters, nodes, and workload entries. The dashboard helps users navigate an organization’s constructs to view nodes assigned to clusters with their respective metadata information and identities registered to nodes etc. The dashboard makes use of pie charts to display high-level information of which agents are associated with which clusters and which workloads are created for each agent if that relationship exists. The constructs relationship tables display metadata information for each construct with the respective relationships. A user can filter through the table/s based upon association, entry, tag, etc. A user can customize a specific relationship by filtering out which relationship is of interest. The customized or filtered relationship can also be exported to a CSV (Comma Separated Values) format to download locally or the specific link can be shared with another user as required.

Tornjak Dashboard View
Figure 13: Tornjak Dashboard View

Adding Static Typing to Tornjak

We have also added static typing using typescript for easier expansion to a large-scale system by avoiding the nightmare of breaking our current code. Initially, the frontend code was purely written in javascript, and js is dynamically typed, now as everything in the frontend is converted to typescript, variables are strictly defined on what they can be. All components including redux now support typing. These add value to our Tornjak framework as the system becomes more robust as we add more functionality and expand the interface for users and clients to use with ease. And as Tornjak is currently open-source it guides new developers on developing Tornjak faster to an even better product.

Adding User Interface Unit Tests to Tornjak

We have also written unit tests for our user interface framework mainly for testing the various components, behaviors, and expectations. Mocking of how fetching of data behaves from the real access point interfaces, how a real browser renders the specific components within the Tornjak application, how the user interface uses sessions and cookies, testing of the state management framework we put in place, testing of navigation between different links within applications and etc.

Conclusion

Tornjak is an open-source project actively under development. If managing workload identities in the current world is of interest to you we are always looking for people to contribute, share ideas, comments or give Tornjak a go. For more information on Tornjak check out the Tornjak GitHub repo and the Tornjak website.

--

--