Skip to content

Go SDK

The Go SDK provides a client for integrating with Subnoto’s API. It handles Oak tunnel encryption, RFC 9421 HTTP signature authentication, and exposes typed API services generated from the OpenAPI specification.

Download the release tarball for your platform from the GitLab releases page or the GitLab Package Registry:

Terminal window
# Linux x86_64
curl -LO https://gitlab.com/api/v4/projects/75972071/packages/generic/subnoto-api-client-go/<VERSION>/subnoto-api-client-go-<VERSION>-linux-x86_64.tar.gz
# macOS arm64
curl -LO https://gitlab.com/api/v4/projects/75972071/packages/generic/subnoto-api-client-go/<VERSION>/subnoto-api-client-go-<VERSION>-darwin-aarch64.tar.gz

Replace <VERSION> with the latest release tag (for example 2.16.0).

Extract the archive and add it as a local module replacement in your go.mod:

Terminal window
mkdir -p third_party/subnoto-sdk
tar xzf subnoto-api-client-go-<VERSION>-linux-x86_64.tar.gz -C third_party/subnoto-sdk
go.mod
require gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go v0.0.0
replace gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go => ./third_party/subnoto-sdk

The tarball includes the SDK source (subnoto/), the generated OpenAPI client (client/), Oak session bindings (oak_session_go/), the pre-built native library (lib/liboak_session_go.so, .dylib on macOS, or .dll on Windows), and go.mod.

The Oak session bindings use CGo and must link against the native library:

Terminal window
SDK_DIR=./third_party/subnoto-sdk
CGO_LDFLAGS="-L${SDK_DIR}/lib -loak_session_go" \
go build ./...

At runtime, the native library must be on the library search path:

Terminal window
LD_LIBRARY_PATH=${SDK_DIR}/lib ./myapp # Linux
DYLD_LIBRARY_PATH=${SDK_DIR}/lib ./myapp # macOS

On Windows, copy oak_session_go.dll next to your executable or add the lib\ directory to your PATH. The DLL requires the Visual C++ Redistributable.

Set your credentials as environment variables — SubnotoConfig picks them up automatically.

Terminal window
export SUBNOTO_ACCESS_KEY="your-access-key"
export SUBNOTO_SECRET_KEY="your-secret-key-hex"
package main
import (
"context"
"fmt"
"log"
"os"
"gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go/subnoto"
oak "gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go/oak_session_go"
)
func main() {
factory := func(unattested bool, attesterKey []byte) (subnoto.OakSession, error) {
var key *[]byte
if attesterKey != nil {
key = &attesterKey
}
return oak.NewOakClientSession(unattested, key)
}
client, err := subnoto.NewClient(&subnoto.SubnotoConfig{
AccessKey: os.Getenv("SUBNOTO_ACCESS_KEY"),
SecretKey: os.Getenv("SUBNOTO_SECRET_KEY"),
}, factory)
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx := context.Background()
whoami, _, err := client.Utils.PublicUtilsWhoamiPost(ctx).
Body(map[string]interface{}{}).Execute()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Team: %s\n", whoami.GetTeamName())
workspaces, _, err := client.Workspace.PublicWorkspaceListPost(ctx).
Body(map[string]interface{}{}).Execute()
if err != nil {
log.Fatal(err)
}
for _, ws := range workspaces.GetWorkspaces() {
fmt.Printf("Workspace: %s (%s)\n", ws.GetName(), ws.GetUuid())
}
}
FieldEnvironment variableDescription
AccessKeySUBNOTO_ACCESS_KEYAPI access key from your team settings
SecretKeySUBNOTO_SECRET_KEYAPI secret key (hex-encoded) from your team settings

In most Public API endpoints, workspaceUuid is optional. When omitted, the team’s default workspace is used. This keeps code simple when you use a single workspace. To target a specific workspace, pass workspaceUuid in the request body.

Per-endpoint details are in the OpenAPI specifications.

The SubnotoClient exposes typed API services as fields for each API group:

ServiceFieldDescription
Envelopeclient.EnvelopeCreate, send, sign envelopes and manage documents
Workspaceclient.WorkspaceList and manage workspaces
Contactclient.ContactCreate and manage contacts
Templateclient.TemplateList templates
Logsclient.LogsView audit logs
Authenticationclient.AuthenticationCreate iframe tokens for embedded signing
Webhookclient.WebhookManage webhooks
Utilsclient.UtilsUtility endpoints (whoami)

You can also send raw JSON requests with client.Post("/public/utils/whoami", struct{}{}) when you do not need the generated client.

API errors are returned from the generated client’s Execute() methods. The SDK also defines SubnotoError for structured error information:

import "gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go/subnoto"
// Errors from Execute() include HTTP status and response body details.
// SubnotoError provides StatusCode and Message when available.
var _ *subnoto.SubnotoError

The Go SDK uses the oak_session_go native library (UniFFI-generated bindings) to establish an encrypted tunnel with Subnoto’s AMD SEV-SNP enclaves. This ensures end-to-end encryption between your application and the enclave, with cryptographic attestation that the server is running in a genuine secure enclave.

The tunnel is established automatically when creating a SubnotoClient. Session management, including automatic retry on tunnel errors, is handled transparently by the tunnel transport.