← Main Guide Terraform Vault & Secrets API & SDKs Parent/Child

API Architecture

The StrongDM API is built on gRPC with a request signature model inspired by AWS V4 signing. You don't use bearer tokens alone -- every request is cryptographically signed, which means the secret key never travels over the wire. This protects against replay attacks and message tampering.

You interact with the API exclusively through one of the four official SDKs. There's no REST endpoint to hit directly. The SDKs handle all the gRPC plumbing, request signing, and pagination.

What You Can Do

R
Resources
Create, list, update, delete datasources, servers, clusters, clouds, and websites programmatically.
A
Accounts
Manage users and service accounts. Create, suspend, delete, and list accounts with filtering.
P
Access Control
Manage roles, access rules, account attachments, and approval workflows.
H
History & Audit
Query change history for accounts, resources, roles. Stream activity logs for SIEM integration. View SSH session replays.

Domain Objects

The API is organized around domain objects that map to StrongDM concepts. Each has standard CRUD operations (Create, Read, Update, Delete) plus List with filtering.

Domain ObjectWhat It Represents
AccountsUsers and service accounts
AccountAttachmentsUser-to-role assignments
ResourcesAll resource types (databases, servers, clusters, etc.)
RolesNamed collections of access rules
RoleAccessRulesStatic or dynamic access rules on roles
NodesGateways and relays
SecretStoresSecret store integrations
AccountsHistoryChange history for accounts (Enterprise: 13 months; Standard: 30 days)
ResourcesHistoryChange history for resources
ActivitiesAdmin and user activity logs

API Keys

Every SDK interaction requires an API key pair: an access key (hex string like auth-0123abcd) and a secret key (Base64 string). The access key identifies the request; the secret key signs it.

Creating API Keys

  1. Open the Admin UI
    Go to Principals > Tokens.
  2. Add API Key
    Click Add API key. Give it a descriptive name. Set an expiration date. Choose permissions (minimum: the CRUD operations your automation needs).
  3. Copy both keys
    Copy the access key and secret key immediately. The secret is shown only once.
Key Safety

API keys remain usable even if the user who created them is suspended. When suspending a user, the Admin UI will ask if their API keys should be deleted. Credential rotation is not currently available -- if a key is compromised, delete it and create a new one.

Best Practices


SDK Setup & Usage

All four SDKs use semantic versioning with no compatibility guarantee between major versions. Pin your dependency to the major version you're on.

Installation

terminal
pip install strongdm

Connect and List Users

list_users.py
import os
import strongdm

client = strongdm.Client(
    os.getenv("SDM_API_ACCESS_KEY"),
    os.getenv("SDM_API_SECRET_KEY"),
)

# List all accounts
for account in client.accounts.list(""):
    print(account)

Create a User

create_user.py
import os
import strongdm

client = strongdm.Client(
    os.getenv("SDM_API_ACCESS_KEY"),
    os.getenv("SDM_API_SECRET_KEY"),
)

user = strongdm.User(
    first_name="Jane",
    last_name="Doe",
    email="[email protected]",
)
response = client.accounts.create(user)
print(f"Created user: {response.account.id}")

Create a Resource

create_resource.py
import os
import strongdm

client = strongdm.Client(
    os.getenv("SDM_API_ACCESS_KEY"),
    os.getenv("SDM_API_SECRET_KEY"),
)

postgres = strongdm.Postgres(
    name="prod-postgres",
    hostname="pg.internal.example.com",
    port=5432,
    database="production",
    username="sdm_user",
    password="secret",
    tags={"env": "production", "team": "platform"},
)
response = client.resources.create(postgres)
print(f"Created resource: {response.resource.id}")

Grant Access (Role + Attachment)

grant_access.py
import os
import strongdm

client = strongdm.Client(
    os.getenv("SDM_API_ACCESS_KEY"),
    os.getenv("SDM_API_SECRET_KEY"),
)

# Create a role
role = strongdm.Role(name="SRE Team")
role_resp = client.roles.create(role)
role_id = role_resp.role.id

# Add a dynamic access rule (all production resources)
rule = strongdm.AccessRule(
    tags={"env": "production"},
)
client.role_access_rules.create(strongdm.RoleAccessRule(
    role_id=role_id,
    access_rules=[rule],
))

# Attach a user to the role
attachment = strongdm.AccountAttachment(
    account_id="a-0123456789",
    role_id=role_id,
)
client.account_attachments.create(attachment)

SDK reference: strongdm.github.io/strongdm-sdk-python-docs

Installation

terminal
go get github.com/strongdm/strongdm-sdk-go

Connect and List Users

main.go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    sdm "github.com/strongdm/strongdm-sdk-go"
)

func main() {
    accessKey := os.Getenv("SDM_API_ACCESS_KEY")
    secretKey := os.Getenv("SDM_API_SECRET_KEY")

    client, err := sdm.New(accessKey, secretKey)
    if err != nil {
        log.Fatal("failed to create client:", err)
    }

    ctx, cancel := context.WithTimeout(
        context.Background(), 30*time.Second,
    )
    defer cancel()

    // List all accounts
    users, err := client.Accounts().List(ctx, "")
    if err != nil {
        log.Fatal("failed to list accounts:", err)
    }
    for users.Next() {
        user := users.Value()
        fmt.Println(user)
    }
    if err := users.Err(); err != nil {
        log.Fatal("iteration error:", err)
    }
}

Filtering

filter.go
// Only return users named "Alice"
users, err := client.Accounts().List(ctx, "firstname:Alice")

SDK reference: pkg.go.dev/github.com/strongdm/strongdm-sdk-go

Installation (Maven)

pom.xml
<dependency>
  <groupId>com.strongdm</groupId>
  <artifactId>strongdm-sdk-java</artifactId>
  <version>LATEST</version>
</dependency>

Connect and List Users

ListUsers.java
import com.strongdm.api.*;

public class ListUsers {
    public static void main(String[] args)
            throws Exception {
        Client client = new Client(
            System.getenv("SDM_API_ACCESS_KEY"),
            System.getenv("SDM_API_SECRET_KEY")
        );
        Iterable<Account> accounts =
            client.accounts().list("");
        for (Account account : accounts) {
            System.out.println(account);
        }
    }
}

SDK reference: github.com/strongdm/strongdm-sdk-java

Installation

terminal
gem install strongdm

Connect and List Users

list_users.rb
require "strongdm"

client = SDM::Client.new(
  ENV["SDM_API_ACCESS_KEY"],
  ENV["SDM_API_SECRET_KEY"],
)

users = client.accounts.list("")
users.each do |user|
  p user
end

SDK reference: github.com/strongdm/strongdm-sdk-ruby

Pagination

When a List operation returns many results, the SDK handles pagination automatically. In Ruby and Python, the result is an iterator you loop over. In Go, you call Next() / Value() explicitly. You don't need to manually manage page tokens.

History and Audit Queries

History domain objects (like AccountsHistory) let you see what changed over time -- not just the current state. You specify a time range and get back a record of all changes.

Enterprise plan Up to 13 months of history Standard plan 30 days, results may be truncated to 20 rows

CLI Admin Reference

The sdm CLI lets you manage StrongDM with your user credentials (after sdm login). The sdm admin subcommands cover the same operations as the API, useful for scripting and quick lookups.

Authentication

terminal
# Log in (opens browser for SSO if configured)
sdm login

# Log out
sdm logout

# Check status
sdm status

Resource Management

terminal
# List all resources (all types)
sdm admin resources list

# List with extended detail
sdm admin resources list -e

# JSON output (for piping to jq)
sdm admin resources list --json

# Filter by tag
sdm admin resources list --filter "tag:env=production"

# List only datasources
sdm admin datasources list -e

# List only servers
sdm admin servers list -e

# Add an SSH server
sdm admin ssh create \
  --name "web-server-01" \
  --hostname 10.0.1.50 \
  --port 22 \
  --username ubuntu \
  --tags "env=production,role=web"

# Delete a resource
sdm admin resources delete rs-0123456789abcdef

User & Service Account Management

terminal
# List all users
sdm admin users list

# List service accounts
sdm admin services list

# Create a service account
sdm admin services create --name "ci-deploy-bot"

# Suspend a user
sdm admin users suspend a-0123456789abcdef

# Assign a user to a role
sdm admin users assign --role "SRE Team" --user "[email protected]"

Role & Access Management

terminal
# List roles
sdm admin roles list

# Create a role
sdm admin roles create --name "Database Team"

# List healthchecks for all nodes/resources
sdm admin healthchecks list

Audit Log Export

terminal
# Export activities from a start date (CSV)
sdm audit activities --from "2026-01-01"

# Export as JSON
sdm audit activities --from "2026-01-01" -j

# Export to file
sdm audit activities --from "2026-01-01" -o activities.csv

# Export connection queries
sdm audit queries --from "2026-01-01" -j

Useful Flags

FlagWhat It Does
-e, --extendedShow detailed information for each item
--json, -jOutput as JSON (great for piping to jq)
--filterFilter results (e.g., field:name, tag:key=value)
--timeoutSet time limit for the command
-h, --helpHelp text for any command

Full CLI Command Tree

sdm admin subcommands
sdm admin
├── datasources # list, add, clone, update, delete
├── servers # list, add, clone, update, delete
├── clusters # list, add, clone, update, delete
├── clouds # list, add, clone, update, delete
├── websites # list, add, clone, update, delete
├── resources # list, delete (all types)
├── nodes # list, create, delete
├── users # list, create, suspend, assign
├── services # list, add, suspend, rotate, grant
├── roles # list, create, delete
├── tokens # list, create, delete (API keys)
├── secretstores # list, create, update, delete
├── secretengines # list, create, update, delete
├── policies # list, create, update, delete
├── ports # list, override
├── healthchecks # list, run
├── identities # list, manage aliases
├── organization # settings
└── workflows # approval workflows

Common Operations by Task

Side-by-side reference for common tasks across Python SDK, CLI, and Terraform.

TaskPython SDKCLI
List all resources client.resources.list("") sdm admin resources list
Create a user client.accounts.create(User(...)) sdm admin users create ...
Suspend a user client.accounts.delete(id) sdm admin users suspend <id>
Create a role client.roles.create(Role(...)) sdm admin roles create --name "..."
Attach user to role client.account_attachments.create(...) sdm admin users assign --role ... --user ...
Export audit logs client.activities.list(...) sdm audit activities --from ...

Automation Patterns

User Lifecycle Automation

Sync users from your IdP, auto-assign roles based on attributes, and clean up on departure.

sync_users.py
import os
import strongdm

client = strongdm.Client(
    os.getenv("SDM_API_ACCESS_KEY"),
    os.getenv("SDM_API_SECRET_KEY"),
)

# Find all users in the "engineering" role
eng_role = None
for role in client.roles.list(""):
    if role.name == "Engineering":
        eng_role = role
        break

# List current members
current = set()
for att in client.account_attachments.list(""):
    if att.role_id == eng_role.id:
        current.add(att.account_id)

print(f"Engineering role has {len(current)} members")

Bulk Resource Onboarding

onboard_databases.py
import os
import strongdm

client = strongdm.Client(
    os.getenv("SDM_API_ACCESS_KEY"),
    os.getenv("SDM_API_SECRET_KEY"),
)

databases = [
    {"name": "prod-pg-01", "host": "pg1.internal", "db": "app"},
    {"name": "prod-pg-02", "host": "pg2.internal", "db": "analytics"},
    {"name": "staging-pg", "host": "pg-staging.internal", "db": "staging"},
]

for db in databases:
    resource = strongdm.Postgres(
        name=db["name"],
        hostname=db["host"],
        port=5432,
        database=db["db"],
        username="sdm_user",
        password=os.getenv("DB_PASSWORD"),
        tags={"env": "production", "team": "data"},
    )
    resp = client.resources.create(resource)
    print(f"Created: {resp.resource.name} ({resp.resource.id})")

Audit Log Export to SIEM

terminal
# Export last 24 hours of activities as JSON, pipe to your SIEM
sdm audit activities --from "$(date -d '24 hours ago' +%Y-%m-%d)" -j | \
  curl -X POST https://siem.example.com/api/ingest \
    -H "Content-Type: application/json" -d @-

CI/CD: Dynamic Resource Registration

register_new_rds.sh
#!/bin/bash
# Called after Terraform creates a new RDS instance
# Registers it with StrongDM and tags it for auto-access

export SDM_API_ACCESS_KEY="$SDM_KEY"
export SDM_API_SECRET_KEY="$SDM_SECRET"

sdm admin datasources create postgres \
  --name "$RDS_IDENTIFIER" \
  --hostname "$RDS_ENDPOINT" \
  --port 5432 \
  --database "$DB_NAME" \
  --username "$DB_USER" \
  --password "$DB_PASS" \
  --tags "env=production,team=platform,managed-by=ci"
Tip

Tag resources consistently from CI/CD. If your roles use dynamic access rules based on tags, newly registered resources are automatically accessible to the right teams without any additional StrongDM configuration.

SCIM Integration

StrongDM supports SCIM 2.0 for automated user provisioning and deprovisioning. This is separate from the SDK API and is typically configured through your IdP (Okta, Entra, OneLogin, JumpCloud, or a generic SCIM client).

SCIM handles user sync and group-to-role mapping, so you don't need to write SDK code for basic provisioning if your IdP supports SCIM. Use the SDK/API for operations beyond what SCIM covers, like resource management, access rules, and audit queries.


Quick Reference

SDKInstallGitHub
Pythonpip install strongdmstrongdm-sdk-python
Gogo get github.com/strongdm/strongdm-sdk-gostrongdm-sdk-go
JavaMaven: com.strongdm:strongdm-sdk-javastrongdm-sdk-java
Rubygem install strongdmstrongdm-sdk-ruby

Note

Content sourced from docs.strongdm.com and the StrongDM SDK repositories on GitHub, March 2026. For the latest SDK versions and full API reference, see the individual SDK docs linked above.