Agent instructions, skills, SSH host aliases and expansion triggers are worth having identical on every machine one person owns, and belong in none of the shared configuration. They live in user/ now, with a manifest saying where each piece goes and a link-user stage that puts it there. That stage does nothing unless the machine said yes. Somebody who clones Panama to try the desktop keeps their own ~/.claude/CLAUDE.md exactly where it was; the question names the destinations and defaults to no. Anything displaced goes to config/old rather than being deleted. ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md were byte-identical copies of one file, which is the drift this exists to prevent. Also adds the vitals toggles for the battery and Claude usage readouts, which had preferences and no way to reach them.
5.9 KiB
SDK Integration
For applications that need to fetch secrets programmatically — not just as environment variables, but within application logic. All SDKs follow the same pattern: initialize → authenticate → fetch secrets.
All SDKs cache secrets and fall back to cached values if requests fail. If no cache exists, they fall back to process.env (or equivalent).
Quick reference
| Language | Package | Min version |
|---|---|---|
| Node.js | @infisical/sdk |
Node 20+ (v5+) |
| Python | infisicalsdk |
Python 3.7+ |
| Go | github.com/infisical/go-sdk |
Go 1.19+ |
| Java | com.infisical:sdk |
Java 11+ |
| .NET | Infisical.Sdk |
.NET 6+ |
| Ruby | infisical-sdk |
Ruby 2.7+ |
Node.js
npm install @infisical/sdk
import { InfisicalSDK } from '@infisical/sdk';
const client = new InfisicalSDK({
siteUrl: "https://app.infisical.com" // optional, this is the default
});
// Authenticate with a machine identity
await client.auth().universalAuth.login({
clientId: "<machine-identity-client-id>",
clientSecret: "<machine-identity-client-secret>"
});
// List all secrets
const secrets = await client.secrets().listSecrets({
environment: "dev",
projectId: "<your-project-id>",
secretPath: "/"
});
// Get a single secret
const secret = await client.secrets().getSecret({
secretName: "API_KEY",
environment: "prod",
projectId: "<your-project-id>"
});
console.log(secret.secretValue);
// Create a secret
await client.secrets().createSecret({
secretName: "NEW_KEY",
secretValue: "value",
environment: "dev",
projectId: "<your-project-id>"
});
Also supports: updateSecret, deleteSecret, dynamic secrets (leases), KMS encrypt/decrypt.
Python
pip install infisicalsdk
from infisical_sdk import InfisicalSDKClient
client = InfisicalSDKClient(
host="https://app.infisical.com",
cache_ttl=60 # seconds, None to disable
)
client.auth.universal_auth.login(
client_id="<client-id>",
client_secret="<client-secret>"
)
# List secrets
secrets = client.secrets.list_secrets(
project_id="<project-id>",
environment_slug="dev",
secret_path="/"
)
# Get one secret
secret = client.secrets.get_secret(
secret_name="API_KEY",
project_id="<project-id>",
environment_slug="prod"
)
print(secret.secret_value)
Auth methods: Universal Auth, AWS IAM, OIDC, LDAP, Token Auth.
Go
go get github.com/infisical/go-sdk
package main
import (
"context"
"fmt"
infisical "github.com/infisical/go-sdk"
)
func main() {
client := infisical.NewInfisicalClient(context.Background(), infisical.Config{
SiteUrl: "https://app.infisical.com",
AutoTokenRefresh: true,
})
_, err := client.Auth().UniversalAuthLogin("CLIENT_ID", "CLIENT_SECRET")
if err != nil {
panic(err)
}
secret, err := client.Secrets().Retrieve(infisical.RetrieveSecretOptions{
SecretKey: "API_KEY",
Environment: "prod",
ProjectID: "YOUR_PROJECT_ID",
SecretPath: "/",
})
fmt.Println(secret.SecretValue)
}
Auth methods: Universal Auth, GCP (ID Token & IAM), AWS IAM, Azure, Kubernetes, JWT, LDAP, OCI.
Note: Set AutoTokenRefresh: true for long-running processes. For multiple clients, manage context cancellation properly to avoid leaked goroutines.
Java
<dependency>
<groupId>com.infisical</groupId>
<artifactId>sdk</artifactId>
<version>{version}</version>
</dependency>
var sdk = new InfisicalSdk(
new SdkConfig.Builder()
.withSiteUrl("https://app.infisical.com")
.build()
);
sdk.Auth().UniversalAuthLogin("CLIENT_ID", "CLIENT_SECRET");
var secret = sdk.Secrets().GetSecret(
"API_KEY", // secret name
"<project-id>", // project ID
"prod", // environment
"/", // path
null, null, null // optional: expandRefs, includeImports, type
);
System.out.println(secret.getValue());
.NET
dotnet add package Infisical.Sdk
var settings = new InfisicalSdkSettingsBuilder()
.WithHostUri("https://app.infisical.com")
.Build();
var client = new InfisicalClient(settings);
await client.Auth().UniversalAuth().LoginAsync("<client-id>", "<client-secret>");
var secrets = await client.Secrets().ListAsync(new ListSecretsOptions {
EnvironmentSlug = "prod",
SecretPath = "/",
ProjectId = "<project-id>",
SetSecretsAsEnvironmentVariables = true // optional: auto-set as env vars
});
Ruby
gem install infisical-sdk
require 'infisical-sdk'
client = InfisicalSDK::InfisicalClient.new('https://app.infisical.com')
client.auth.universal_auth(
client_id: 'CLIENT_ID',
client_secret: 'CLIENT_SECRET'
)
secret = client.secrets.get(
secret_name: 'API_KEY',
project_id: '<project-id>',
environment: 'prod'
)
puts secret.secret_value
Cache default: 5 minutes. Set to 0 to disable.
When to use SDK vs. CLI
| Scenario | Use |
|---|---|
| Local dev, any framework | CLI (infisical run -- ...) |
| Docker containers | CLI (see docker-integration.md) |
| Need secrets in application logic (not just env vars) | SDK |
| Dynamic secrets / leases | SDK |
| KMS encrypt/decrypt | SDK |
| Kubernetes pods | Operator (see kubernetes-operator.md) or SDK |
| CI/CD pipelines | CLI or OIDC action (see cicd-integration.md) |
Auth method availability by SDK
All SDKs support Universal Auth. Cloud-native auth varies:
| Auth method | Node | Python | Go | Java | .NET | Ruby |
|---|---|---|---|---|---|---|
| Universal Auth | Yes | Yes | Yes | Yes | Yes | Yes |
| AWS IAM | Yes | Yes | Yes | — | — | Yes |
| GCP | — | — | Yes | — | — | Yes |
| Azure | — | — | Yes | — | — | Yes |
| Kubernetes | — | — | Yes | — | — | Yes |
| OIDC | — | Yes | — | — | — | — |
| LDAP | — | Yes | Yes | — | Yes | — |