Skip to main content

Command Palette

Search for a command to run...

Using SPIRE as a Trusted Authority for OpenZiti Identities

Published
5 min read
Using SPIRE as a Trusted Authority for OpenZiti Identities
K

I'm crafting developer experiences with zrok and OpenZiti from NetFoundry

Introduction

Identity management is central to modern network security. This post shows how to use short‑lived X.509 client certificates from SPIRE — the reference runtime for SPIFFE (Secure Production Identity Framework For Everyone) — as OpenZiti identities. OpenZiti is an open‑source zero‑trust networking platform that represents workloads or devices with verifiable identities. Treating SPIRE as a CA lets you issue ephemeral, non‑interactive identities—ideal for workloads such as Kubernetes pods—without exposing services to public networks.

How it works

From OpenZiti’s perspective, SPIRE is another CA that you control. SPIRE issues a client certificate for Workload1. If the issuer is not a root CA, this must be presented with its supporting intermediate issuers. Workload1 has a standard OpenZiti identity configuration, such as the following example, which the deployer must craft, referencing the client cert from SPIRE, the private key, and the trust bundle from the OpenZiti controller.

OpenZiti identity configuration example: work1.json

{
  "ztAPI": "https://ziti.example.com:443",
  "id": {
    "cert": "file://work1.chain.pem",
    "key": "file://work1.key",
    "ca": "file://cas.pem"
  }
}

The client certificate in work1.chain.pem must have URI SAN spiffe://spire1.ziti.example.com/workloads/work1.

The OpenZiti Edge SDK can load this configuration file and connect to OpenZiti services. With this approach, there’s no need to enroll the OpenZiti identity. Each short-lived certificate from SPIRE can be used to obtain a session authorized to perform any operation granted to the OpenZiti identity for which its external ID maps to the SPIFFE ID.

Configuring OpenZiti to trust SPIRE

Let's walk through an example procedure for configuring OpenZiti to trust a SPIRE CA, define the OpenZiti identity roles for Workload1's SPIFFE ID, and connect to an OpenZiti service with the client certificate from SPIRE.

Step 1: Obtain the trust bundle from the OpenZiti Controller

Each workload’s OpenZiti identity configuration file must reference this file in the id.ca property.

curl -skSf https://ziti.example.com:443/.well-known/est/cacerts \
| base64 -d \
| openssl pkcs7 -inform DER -outform PEM -print_certs \
| tee ./cas.pem

Step 2: Prove ownership and register the SPIRE CA with OpenZiti

You can use the ziti CLI if you have direct access to the SPIRE CA’s private key to verify it in a single step.

ziti edge create ca "spire1" ./spire/certs/root.cert \
    --location "SAN_URI" \
    --matcher "SCHEME" \
    --matcher-criteria "spiffe" \
    --parser "NONE" \
    --auth

ziti edge verify ca "spire1" \
    --cacert ./spire/certs/root.cert \
    --cakey ./spire/keys/root.key

Alternatively, request a client cert from SPIRE with the verification token as the CN part of the DN. Obtain the verification token (e.g., S6ZLJD7XL8) by listing the newly created CA.

ziti edge list cas

Step 3: Issue a client certificate with the verification token

Use the client certificate, with the verification token as the CN value of the subject DN, to prove ownership of the SPIRE CA.

ziti edge verify ca "spire1" \
    --cert ./S6ZLJD7XL8.cert

Now, the OpenZiti controller trusts the SPIRE CA to issue client certificates for OpenZiti identities.

Provisioning a workload identity

Create an OpenZiti identity with the desired role and the SPIFFE ID that SPIRE will assign to this workload. The role must match the OpenZiti policies that authorize the identity to use OpenZiti services and routers.

ziti edge create identity "work1" \
    --external-id spiffe://spire1.ziti.example.com/workloads/work1 \
    --role-attributes httpbin-clients

Finally, you only need the standard OpenZiti identity configuration JSON file described earlier, referencing the client cert from SPIRE with a matching SPIFFE ID in the URI SAN.

Any OpenZiti Edge SDK can load this standard identity configuration file and use OpenZiti services.

Using the identity with the zitify tool

Here's how it would look to use the zitify tool on Linux—a shell script that invokes the OpenZiti Python SDK to “wrap” another program with Ziti sauce via LD_PRELOAD. We'll use curl in this example. The OpenZiti service address (i.e., the “intercept”) in this case is httpbin.ziti.internal:80.

zitify -i work1.json curl --data ziti=works http://httpbin.ziti.internal/post

The response is JSON from Httpbin containing the request’s form data.

Using the identity with a tunneler

You can use an OpenZiti identity configuration file with OpenZiti tunnelers, like ziti-edge-tunnel, which load identities from a standard configuration file by placing the file in the identity directory before starting the tunnel. The tunneler must also be able to read the referenced cert, key, and CA files.

Using the identity with the CLI

Authentication works identically for a network administrator, so a SPIRE-authenticated workload can also operate on the OpenZiti network via the management API.

For example, you can provision an admin identity and use its configuration file with the ziti edge administrative CLI commands.

ziti edge create identity "admin2" \
    --external-id spiffe://spire1.ziti.example.com/workloads/admin2 \
    --admin

Create an identity configuration file referencing the client certificate issued by SPIRE.

OpenZiti identity configuration example: admin2.json

{
  "ztAPI": "https://ziti.example.com:443",
  "id": {
    "cert": "file://admin2.chain.pem",
    "key": "file://admin2.key",
    "ca": "file://cas.pem"
  }
}

The client certificate in admin2.chain.pem must have URI SAN spiffe://spire1.ziti.example.com/workloads/admin2.

Then, log in to the OpenZiti management API using the configuration file.

ziti edge login --file admin2.json

...and perform administrative tasks.

ziti edge list summary

Conclusion

By leveraging SPIRE as a trusted CA within OpenZiti, we can streamline the management of workload identities, especially for short-lived, non-interactive services. This integration enhances security and simplifies identity provisioning, making your zero-trust network more robust and easier to manage.

References