Skip to content

About

Go SDK for the One Identity Safeguard for Privileged Passwords Web API

Resources

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

64 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Reference Release License

safeguard-go

One Identity Safeguard SDK for Go.

safeguard-go is the standalone Go SDK for One Identity Safeguard for Privileged Passwords (SPP). It mirrors the SafeguardDotNet and PySafeguard SDKs with a Go-idiomatic API surface for authentication, Invoke-style API calls, Application-to-Application (A2A) workflows, and events.

The module is pre-1.0; the public API may change before the first v1.0.0 release. See docs/versioning.md for the versioning and release policy.

Features

  • Authentication — Resource Owner Grant username/password, certificate login over mutual TLS, PKCE headless (with MFA/secondary-factor support), existing user token, and anonymous access. Interactive external-browser and device-code logins ship as optional add-on packages so headless consumers keep a lean dependency graph.
  • Invoke and Service surface — Connect, Get/Post/Put/Delete helpers, generic Invoke, typed InvokeTyped[T], query parameters, headers, per-request API-version and host overrides, Response, and Stream/Upload/Download for large payloads.
  • Application-to-Application (A2A) — password, SSH private-key, and API-key secret retrieval; password and private-key set (write-back); access-request brokering; retrievable-account discovery; and credential-change events.
  • Events — an owned SignalR-over-WebSocket implementation with one-shot and persistent (auto-reconnecting) listeners for both user sessions and A2A credential-change streams.
  • TLS secure by default — HTTPS-only appliance endpoints (a non-https host is rejected), system trust by default, custom CA bundles that replace the system trust store, an additive server-certificate validator callback, and a loud insecure override for bootstrap/test appliances.
  • Typed errors — API, authentication (401), authorization (403), not-found (404), transport, and sentinel errors designed for errors.Is/errors.As.
  • Secret hygiene — the Secret type wraps sensitive values, redacts them from strings/logs/errors/JSON, copies on construction and exposure, and best-effort zeroes on close.

The only third-party dependency is github.com/coder/websocket (used by the event listeners). The browser and devicecode add-ons are separate packages, so importing the root package alone stays dependency-light.

Installation

go get github.com/OneIdentity/safeguard-go

The SDK requires Go 1.21 or later.

Quick start

package main

import (
    "context"
    "log"

    "github.com/OneIdentity/safeguard-go"
)

func main() {
    ctx := context.Background()

    cred := safeguard.UsernamePassword(
        "local",
        "Admin",
        safeguard.NewSecretString("correct horse battery staple"),
    )

    client, err := safeguard.Connect(ctx, "safeguard.sample.corp", cred)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    resp, err := client.Get(ctx, safeguard.Core, "Me")
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("GET Me -> %d\n%s\n", resp.StatusCode, resp.Body)
}

Recent Safeguard appliances commonly disable Resource Owner Grant (ROG). New applications should prefer PKCE, browser, device-code, certificate, or token-based flows as appropriate. PKCEHeadless is the recommended flow for automation because it does not depend on ROG.

To decode a JSON response into a Go value, use the generic helper:

type me struct {
    UserName    string `json:"UserName"`
    DisplayName string `json:"DisplayName"`
}

info, err := safeguard.InvokeTyped[me](ctx, client, safeguard.MethodGet, safeguard.Core, "Me", nil)
if err != nil {
    log.Fatal(err)
}
log.Printf("signed in as %s (%s)", info.UserName, info.DisplayName)

Samples

The samples directory has a small, standalone program for each flow — every authentication method, the A2A retrieval/set/broker workflows, and the event listeners. Each sample takes its inputs as flags; run one with, for example:

go run ./samples/pkce -appliance safeguard.example.com -username Admin -insecure

See samples/README.md for the full list and the shared flags.

API version

The SDK targets Safeguard API v4 by default for Safeguard 7.0 and later. Override it per client with WithAPIVersion or per request with WithAPIVersionOverride (for example "v3" for legacy compatibility); the SDK does not auto-detect the API version.

TLS versions and certificate authentication

Safeguard for Privileged Passwords 9.0 enables TLS 1.3. safeguard-go works against both 8.x and 9.0 with no configuration changes and is secure by default: every transport negotiates TLS 1.2 or higher.

Default: hybrid per transport

The negotiated protocol window defaults to a TLS 1.2 floor on every transport, with the ceiling chosen per transport. Password, token, and PKCE traffic (the server-trust transport) is free to negotiate TLS 1.3 where the appliance supports it, while certificate login and A2A (the client-certificate transport) are capped at TLS 1.2.

Certificate authentication requires the client to present its certificate in response to a request the appliance makes after the handshake. Go's TLS stack answers that only at TLS 1.2 (via renegotiation); it neither offers the TLS 1.3 post_handshake_auth extension nor answers a post-handshake CertificateRequest, so a TLS 1.3 certificate-auth attempt against the appliance Standard binding fails with 60094 Authorization is denied. Capping the certificate transport at TLS 1.2 keeps certificate and A2A auth working out of the box while everything else still gets TLS 1.3. That transport also uses HTTP/1.1 (the HTTP/2 upgrade is disabled), because HTTP/2 disallows the post-handshake certificate exchange.

Pinning the TLS version (opt-in)

WithMinTLSVersion and WithMaxTLSVersion take a crypto/tls version constant and are passed to Connect. Values pass straight through to crypto/tls, so protocol versions added in the future need no SDK change.

import (
    "crypto/tls"

    "github.com/OneIdentity/safeguard-go"
)

// Require TLS 1.3 on the Standard host (fail closed against anything lower).
// This enforces 1.3 for password/token/PKCE auth; certificate and A2A auth
// need the Cert SNI host instead — see the third example below.
client, err := safeguard.Connect(ctx, "safeguard.sample.corp", cred,
    safeguard.WithMinTLSVersion(tls.VersionTLS13))

// Pin the connection to TLS 1.2 (interim, for environments not ready for 1.3)
client, err = safeguard.Connect(ctx, "safeguard.sample.corp", cred,
    safeguard.WithMaxTLSVersion(tls.VersionTLS12))

// Certificate/A2A auth over TLS 1.3: connect to the appliance Cert SNI
// hostname (NOT the Standard host, which caps cert auth at TLS 1.2 and would
// fail closed here). Setting a bound lifts the automatic cert-transport cap;
// the SNI binding requests the client certificate in-handshake, which Go can
// answer at TLS 1.3.
client, err = safeguard.Connect(ctx, "spp-tls13.sample.corp", cred,
    safeguard.WithMinTLSVersion(tls.VersionTLS13))

Setting either bound turns off the automatic TLS 1.2 cap on the certificate transport, putting you fully in control. This is what enables certificate and A2A authentication over TLS 1.3, but it only works against the appliance Cert SNI hostname — a binding that requests the client certificate during the handshake, which Go's TLS stack can answer at TLS 1.3. Pointing WithMinTLSVersion(tls.VersionTLS13) at the Standard host instead (as in the first example above) makes certificate and A2A auth fail closed with 60094 Authorization is denied, because that binding still relies on the post-handshake certificate request Go only answers at TLS 1.2. Password, token, and PKCE auth negotiate TLS 1.3 on either host. A maximum lower than the minimum is rejected at connect time, and lowering the minimum below TLS 1.2 is a discouraged escape hatch for legacy interoperability that should never be used in production.

The default (no options) negotiates the highest mutually supported version and works against both 8.x (TLS 1.2 ceiling) and 9.0 (TLS 1.3) with no flags. Requiring TLS 1.3 against an appliance that tops out at TLS 1.2 (such as SPP 8.x) fails the handshake by design rather than silently downgrading. Server-certificate trust is configured separately with WithCABundle, WithServerCertValidator, and the bootstrap-only WithInsecureTLS.

Support

One Identity open source projects are supported through GitHub issues and the One Identity Community. Open an issue in this repository to report a bug or request a feature.

License

Apache License 2.0. See LICENSE and NOTICE.

About

Go SDK for the One Identity Safeguard for Privileged Passwords Web API

Resources

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages