This is the sixth post in the series about tpm-ca-certificates.
If you’re new to this series, I recommend starting with the first one.
In this post, we’ll explore how the SDK works for interacting with tpm-ca-certificates.
Currently, only a Go SDK (in beta) is available. SDKs for Python and Rust are under consideration.

Note: image generated by ChatGPT
The SDK provides a simple interface to interact with the project while abstracting much of the complexity. In fact, tpmtb is built on top of this SDK.
Let’s take a closer look at the key features offered.
Features
1. Bundle Download and Validation
In part 3, we briefly presented the different steps involved in verifying the integrity and provenance of a bundle. Since the process is quite complex, it’s strongly recommended to use the SDK to simplify these operations.
Examples
The SDK always validates the integrity and provenance of the bundle before making it available for use.
package main
import (
"context"
"fmt"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
// Get the latest verified bundle
tb, err := apiv1beta.GetTrustedBundle(ctx)
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
// Bundle is verified and ready to use!
metadata := tb.GetRootMetadata()
fmt.Printf("Bundle date: %s\n", metadata.Date)
fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
package main
import (
"context"
"fmt"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
// Get a specific bundle by date
tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
Date: "2026-02-04",
})
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
// Bundle is verified and ready to use!
metadata := tb.GetRootMetadata()
fmt.Printf("Bundle date: %s\n", metadata.Date)
fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
package main
import (
"context"
"fmt"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
// Load bundle in offline mode
tb, err := apiv1beta.LoadTrustedBundle(ctx, apiv1beta.LoadConfig{
OfflineMode: true,
CachePath: "/path/to/cache/directory",
})
if err != nil {
log.Fatalf("Failed to load bundle: %v", err)
}
// Bundle is verified and ready to use!
metadata := tb.GetRootMetadata()
fmt.Printf("Bundle date: %s\n", metadata.Date)
fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
2. Auto-Renew
To ensure the bundle stays up to date, the SDK offers an auto-renewal feature (enabled by default).
The auto-renewal job regularly checks if a new bundle is available and automatically downloads it (while verifying its integrity).
Examples
The SDK always validates the integrity and provenance of the bundle before making it available for use.
package main
import (
"context"
"fmt"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
AutoUpdate: apiv1beta.AutoUpdateConfig{
Interval: "24h",
},
})
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
// Bundle will be automatically updated according to the specified interval
metadata := tb.GetRootMetadata()
fmt.Printf("Bundle date: %s\n", metadata.Date)
fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
package main
import (
"context"
"fmt"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
AutoUpdate: apiv1beta.AutoUpdateConfig{
Disabled: true,
},
})
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
// Bundle is verified and ready to use!
metadata := tb.GetRootMetadata()
fmt.Printf("Bundle date: %s\n", metadata.Date)
fmt.Printf("Bundle commit: %s\n", metadata.Commit)
}
In offline mode, auto-renewal is automatically disabled.
3. Certificate Verification
The SDK can validate the trust of an Endorsement Key (EK) certificate.
In Go, some workarounds with the crypto/x509 package are necessary for this to work. The SDK abstracts some of these complexities.
Examples
The SDK always validates the integrity and provenance of the bundle before making it available for use.
package main
import (
"context"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
tb, err := apiv1beta.GetTrustedBundle(ctx)
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
ekCert := getEKCert() // Your implementation
// Verify the EK certificate against the trusted bundle
if err := tb.Verify(ekCert); err != nil {
log.Fatalf("EK certificate verification failed: %v", err)
}
log.Println("EK certificate verified successfully!")
}
A TPM may also store intermediate certificates. The SDK supports this kind of scenario as well.
package main
import (
"context"
"fmt"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
tb, err := apiv1beta.GetTrustedBundle(ctx)
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
ekCert, intermediates := getEKCertAndIntermediates() // Your implementation
// Verify the EK certificate against the trusted bundle
if err := tb.Verify(ekCert, intermediates); err != nil {
log.Fatalf("EK certificate verification failed: %v", err)
}
log.Println("EK certificate verified successfully!")
}
4. Vendor Filtering
You may want to restrict trust to only a limited number of vendors. For example, a company or individual may want to buy from specific vendors.
The SDK handles this by allowing filtering by vendors.
Example
package main
import (
"context"
"log"
"github.com/loicsikidi/tpm-ca-certificates/pkg/apiv1beta"
)
func main() {
ctx := context.Background()
tb, err := apiv1beta.GetTrustedBundle(ctx, apiv1beta.GetConfig{
VendorIDs: []apiv1beta.VendorID{
apiv1beta.AMD,
apiv1beta.NTC,
},
})
if err != nil {
log.Fatalf("Failed to get bundle: %v", err)
}
defer tb.Stop() // stop auto update process
ekCert := getEKCert() // Your implementation
// Verify limit the trust ONLY to the specified vendors
if err := tb.Verify(ekCert); err != nil {
log.Fatalf("EK certificate verification failed: %v", err)
}
log.Println("EK certificate verified successfully!")
}
Conclusion
In this post, we’ve highlighted the various features offered by the SDK. You now have a good understanding of what’s possible and concrete examples of how to use it. In the next post, we’ll introduce a tool built on top of the SDK: tpm-trust.