RESOURCES

Go SDK

SDK to integrate Phase in server-side applications running Go.

Prerequisites


Install the SDK

Install the SDK using go get.

Install

go get github.com/phasehq/golang-sdk/v2/phase

Import the SDK

Import the SDK in your Go files to start using its features.

import "github.com/phasehq/golang-sdk/v2/phase"

Initialize the SDK

Before interacting with the Phase service, initialize the SDK with your service token and the host information.

Parameters:

  • token type string: Your Phase Service Token (pss_service:v1:... or pss_service:v2:...) or User Token (pss_user:v1:...)
  • host type string: The URL of the Phase Console instance. Defaults to https://console.phase.dev if empty.
  • debug type bool: Setting to true will result in a higher level of log verbosity useful when debugging
package main

import (
    "log"
    "github.com/phasehq/golang-sdk/v2/phase"
)

func main() {
    token := "pss_service:v1:....."
    host := "https://console.phase.dev" // Adjust this for a self-hosted instance of Phase
    debug := false // For logging verbosity, disable in production

    p, err := phase.New(token, host, debug)
    if err != nil {
        log.Fatalf("Failed to initialize Phase client: %v", err)
    }
}

Usage

You can get the AppID by going to your application settings in the Phase Console, hovering over UUID under the App section and clicking the Copy button:

hello world

Secret Types

Phase supports three secret types, available as constants:

ConstantValueDescription
phase.SecretTypeSecret"secret"Default — standard encrypted secret
phase.SecretTypeSealed"sealed"Write-only — value cannot be read back after creation
phase.SecretTypeConfig"config"Non-sensitive configuration value

Use phase.ValidateSecretType(t) to validate a type string — returns nil for valid types (including empty string, which defaults to "secret").

Creating Secrets

Define key-value pairs and specify the Environment, App name or ID, and path (optional) to create new Secrets.

Options:

type CreateOptions struct {
    KeyValuePairs []phase.KeyValuePair
    EnvName       string
    AppID         string
    AppName       string // Alternative to AppID
    Path          string
    OverrideValue string
    Type          string // "secret" (default), "sealed", or "config" — applied to all pairs when KeyValuePair.Type is empty
}

type KeyValuePair struct {
    Key   string
    Value string
    Type  string // Per-pair type override; takes precedence over CreateOptions.Type
}
err := p.Create(phase.CreateOptions{
    KeyValuePairs: []phase.KeyValuePair{
        {Key: "API_KEY", Value: "api_secret"},
        {Key: "DB_HOST", Value: "localhost:5432"},
    },
    EnvName: "Production",
    AppID:   "app-id-here",  // Or use AppName: "MyApp"
    Path:    "/api/keys",    // Optional, default path: /
})
if err != nil {
    log.Fatalf("Failed to create secret: %v", err)
}

// Create a sealed secret (write-only)
err = p.Create(phase.CreateOptions{
    KeyValuePairs: []phase.KeyValuePair{
        {Key: "STRIPE_KEY", Value: "sk_live_..."},
    },
    EnvName: "Production",
    AppID:   "app-id-here",
    Type:    phase.SecretTypeSealed,
})

// Create config values (non-sensitive)
err = p.Create(phase.CreateOptions{
    KeyValuePairs: []phase.KeyValuePair{
        {Key: "APP_PORT", Value: "8080"},
        {Key: "LOG_LEVEL", Value: "info"},
    },
    EnvName: "Production",
    AppID:   "app-id-here",
    Type:    phase.SecretTypeConfig,
})

Getting Secrets

Provide the Environment name, App name or ID, and optionally filter by specific keys, tags, and path.

Options:

type GetOptions struct {
    EnvName  string
    AppID    string
    AppName  string // Alternative to AppID
    Keys     []string // Optional: filter by specific key names
    Tag      string   // Optional: filter by tag
    Path     string   // Optional: filter by path (default: /)
    Dynamic  bool     // Optional: include dynamic secrets
    Lease    bool     // Optional: generate leases for dynamic secrets
    LeaseTTL *int     // Optional: lease TTL in seconds
    Raw      bool     // Optional: skip ${REF} reference resolution
}

Each secret is returned as a SecretResult:

type SecretResult struct {
    Key          string
    Value        string
    Comment      string
    Path         string
    Type         string       // "secret", "sealed", or "config"
    Application  string
    Environment  string
    Tags         []string
    Overridden   bool         // true if a personal override is active
    IsDynamic    bool         // true for dynamic secrets
    DynamicGroup string       // provider group label for dynamic secrets
}

Get all secrets

secrets, err := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here", // Or use AppName: "MyApp"
})
if err != nil {
    log.Fatalf("Failed to get secrets: %v", err)
}
for _, s := range secrets {
    log.Printf("%s=%s", s.Key, s.Value)
}

Get specific keys

secrets, err := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here",
    Keys:    []string{"API_KEY", "DB_HOST"},
})

Filter by tag and path

secrets, err := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here",
    Tag:     "backend",
    Path:    "/api/config",
})

Include dynamic secrets with leases

secrets, err := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here",
    Dynamic: true,
    Lease:   true,
})

Updating a Secret

Provide the new value along with the environment name, application name or ID, and key to update an existing secret.

Options:

type UpdateOptions struct {
    EnvName         string
    AppID           string
    AppName         string // Alternative to AppID
    Key             string
    Value           string
    SourcePath      string // Path where the secret currently lives
    DestinationPath string // Optional: move the secret to a new path
    Override        bool   // Set a personal override
    ToggleOverride  bool   // Toggle personal override on/off
    Type            string // "secret", "sealed", or "config" — leave empty to keep existing type
}
result, err := p.Update(phase.UpdateOptions{
    EnvName: "Production",
    AppID:   "app-id-here", // Or use AppName: "MyApp"
    Key:     "API_KEY",
    Value:   "my_updated_api_secret",
})
if err != nil {
    log.Fatalf("Failed to update secret: %v", err)
}

Deleting Secrets

Specify the environment name, application name or ID, keys to delete, and optionally the path.

Options:

type DeleteOptions struct {
    EnvName      string
    AppID        string
    AppName      string // Alternative to AppID
    KeysToDelete []string
    Path         string
}
keysNotFound, err := p.Delete(phase.DeleteOptions{
    EnvName:      "Production",
    AppID:        "app-id-here", // Or use AppName: "MyApp"
    KeysToDelete: []string{"API_KEY", "OLD_SECRET"},
    Path:         "/api/keys", // Optional, default path: /
})
if err != nil {
    log.Fatalf("Failed to delete secret: %v", err)
}
if len(keysNotFound) > 0 {
    log.Printf("Keys not found: %v", keysNotFound)
}

Get raw values without resolving references

secrets, err := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here",
    Raw:     true, // ${REF} syntax is preserved as-is
})

Secret References

Get() automatically resolves ${REF} syntax in secret values before returning results. This includes same-environment (${KEY}), cross-environment (${staging.SECRET_KEY}), cross-app (${backend_api::production.API_KEY}), and path-scoped (${/backend/config/DB_HOST}) references.

// References are resolved automatically — no extra steps needed
secrets, _ := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here",
})

for _, s := range secrets {
    // s.Value already has all ${REF} references resolved
    fmt.Printf("%s=%s\n", s.Key, s.Value)
}

To get raw, unresolved values (e.g. for display or inspection), set Raw: true:

secrets, _ := p.Get(phase.GetOptions{
    EnvName: "Production",
    AppID:   "app-id-here",
    Raw:     true,
})

for _, s := range secrets {
    // s.Value contains the original ${REF} syntax, not the resolved value
    fmt.Printf("%s=%s\n", s.Key, s.Value)
}

Overrides

Create or update a personal override for a secret:

// Create a secret with an override value
err := p.Create(phase.CreateOptions{
    KeyValuePairs: []phase.KeyValuePair{
        {Key: "API_URL", Value: "https://api.example.com"},
    },
    EnvName:       "Development",
    AppID:         "app-id-here",
    OverrideValue: "http://localhost:3000",
})

// Update override for existing secret
_, err := p.Update(phase.UpdateOptions{
    EnvName:  "Development",
    AppID:    "app-id-here",
    Key:      "API_URL",
    Value:    "http://localhost:4000",
    Override: true,
})

// Toggle override on/off
_, err := p.Update(phase.UpdateOptions{
    EnvName:        "Development",
    AppID:          "app-id-here",
    Key:            "API_URL",
    ToggleOverride: true,
})