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.
Installation
Section titled “Installation”Download the release tarball for your platform from the GitLab releases page or the GitLab Package Registry:
# Linux x86_64curl -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 arm64curl -LO https://gitlab.com/api/v4/projects/75972071/packages/generic/subnoto-api-client-go/<VERSION>/subnoto-api-client-go-<VERSION>-darwin-aarch64.tar.gzReplace <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:
mkdir -p third_party/subnoto-sdktar xzf subnoto-api-client-go-<VERSION>-linux-x86_64.tar.gz -C third_party/subnoto-sdkrequire gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go v0.0.0replace gitlab.com/subnoto/subnoto-monorepo-public/libs/api-client-go => ./third_party/subnoto-sdkThe 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.
Building
Section titled “Building”The Oak session bindings use CGo and must link against the native library:
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:
LD_LIBRARY_PATH=${SDK_DIR}/lib ./myapp # LinuxDYLD_LIBRARY_PATH=${SDK_DIR}/lib ./myapp # macOSOn 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.
Quick Start
Section titled “Quick Start”Set your credentials as environment variables — SubnotoConfig picks them up automatically.
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()) }}Configuration
Section titled “Configuration”| Field | Environment variable | Description |
|---|---|---|
AccessKey | SUBNOTO_ACCESS_KEY | API access key from your team settings |
SecretKey | SUBNOTO_SECRET_KEY | API secret key (hex-encoded) from your team settings |
Workspace and workspaceUuid
Section titled “Workspace and workspaceUuid”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.
API Services
Section titled “API Services”The SubnotoClient exposes typed API services as fields for each API group:
| Service | Field | Description |
|---|---|---|
| Envelope | client.Envelope | Create, send, sign envelopes and manage documents |
| Workspace | client.Workspace | List and manage workspaces |
| Contact | client.Contact | Create and manage contacts |
| Template | client.Template | List templates |
| Logs | client.Logs | View audit logs |
| Authentication | client.Authentication | Create iframe tokens for embedded signing |
| Webhook | client.Webhook | Manage webhooks |
| Utils | client.Utils | Utility endpoints (whoami) |
You can also send raw JSON requests with client.Post("/public/utils/whoami", struct{}{}) when you do not need the generated client.
Error Handling
Section titled “Error Handling”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.SubnotoErrorOak Tunnel Encryption
Section titled “Oak Tunnel Encryption”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.