SDKs & Integrations
Java SDK
Official Java SDK for KeyEnv.
Java SDK
Official Java SDK for KeyEnv with Java 11+ support and async/await patterns.
Beta Release: This SDK is currently in development. APIs may change before the stable 1.0 release.
Installation
Maven
Add the JitPack repository and dependency to your pom.xml:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.keyenv</groupId>
<artifactId>java-sdk</artifactId>
<version>v1.1.0</version>
</dependency>Gradle
Add the JitPack repository and dependency to your build.gradle:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.keyenv:java-sdk:v1.1.0'
}Or with Kotlin DSL (build.gradle.kts):
repositories {
maven("https://jitpack.io")
}
dependencies {
implementation("com.github.keyenv:java-sdk:v1.1.0")
}Quick Start
import dev.keyenv.KeyEnv;
public class Application {
public static void main(String[] args) {
KeyEnv client = KeyEnv.create(System.getenv("KEYENV_TOKEN"));
// Load secrets into system properties
int count = client.loadEnv("your-project-id", "production");
System.out.println("Loaded " + count + " secrets");
// Access secrets via System.getProperty
System.out.println(System.getProperty("DATABASE_URL"));
}
}Initialize the Client
Simple Initialization
import dev.keyenv.KeyEnv;
KeyEnv client = KeyEnv.create(System.getenv("KEYENV_TOKEN"));Builder Pattern
For more control, use the builder:
import dev.keyenv.KeyEnv;
import java.time.Duration;
KeyEnv client = KeyEnv.builder()
.token(System.getenv("KEYENV_TOKEN"))
.timeout(Duration.ofSeconds(60))
.cacheTtl(Duration.ofMinutes(5))
.build();Loading Secrets
Load into System Properties
The simplest way to use secrets in your application:
int count = client.loadEnv("project-id", "production");
System.out.println("Loaded " + count + " secrets");
// Access via System.getProperty
String dbUrl = System.getProperty("DATABASE_URL");
String apiKey = System.getProperty("API_KEY");Get Secrets as Map
Get secrets as a key-value map:
import java.util.Map;
Map<String, String> secrets = client.exportSecretsAsMap("project-id", "production");
System.out.println(secrets.get("DATABASE_URL"));
System.out.println(secrets.get("API_KEY"));Export as List
Get secrets with metadata:
import dev.keyenv.types.SecretWithValueAndInheritance;
import java.util.List;
List<SecretWithValueAndInheritance> secrets = client.exportSecrets("project-id", "production");
for (SecretWithValueAndInheritance secret : secrets) {
System.out.println(secret.getKey() + "=" + secret.getValue());
}Managing Secrets
Get a Single Secret
import dev.keyenv.types.SecretWithValue;
SecretWithValue secret = client.getSecret("project-id", "production", "DATABASE_URL");
System.out.println(secret.getValue());
System.out.println(secret.getDescription());Set a Secret
Creates or updates a secret:
client.setSecret("project-id", "production", "API_KEY", "sk_live_...");
// With description
client.setSecret("project-id", "production", "API_KEY", "sk_live_...", "Production API key");Delete a Secret
client.deleteSecret("project-id", "production", "OLD_KEY");Bulk Operations
Bulk Import
Import multiple secrets at once:
import dev.keyenv.types.SecretInput;
import dev.keyenv.types.BulkImportOptions;
import dev.keyenv.types.BulkImportResult;
import java.util.List;
List<SecretInput> secrets = List.of(
new SecretInput("DATABASE_URL", "postgres://localhost/mydb", null),
new SecretInput("REDIS_URL", "redis://localhost:6379", null),
new SecretInput("API_KEY", "sk_test_...", "Test API key")
);
BulkImportResult result = client.bulkImport(
"project-id",
"development",
secrets,
new BulkImportOptions(true) // overwrite existing
);
System.out.println("Created: " + result.getCreated() + ", Updated: " + result.getUpdated());Generate .env File
import java.nio.file.Files;
import java.nio.file.Paths;
String envContent = client.generateEnvFile("project-id", "production");
Files.writeString(Paths.get(".env"), envContent);Projects & Environments
List Projects
import dev.keyenv.types.Project;
import java.util.List;
List<Project> projects = client.listProjects();
for (Project project : projects) {
System.out.println(project.getName() + " (" + project.getId() + ")");
}Get Project Details
import dev.keyenv.types.Project;
Project project = client.getProject("project-id");
System.out.println("Project: " + project.getName());
for (var env : project.getEnvironments()) {
System.out.println(" - " + env.getName());
}List Environments
import dev.keyenv.types.Environment;
import java.util.List;
List<Environment> environments = client.listEnvironments("project-id");
for (Environment env : environments) {
System.out.println(env.getName());
}Async Operations
All methods have async variants that return CompletableFuture:
import java.util.concurrent.CompletableFuture;
// Async secret loading
CompletableFuture<Integer> future = client.loadEnvAsync("project-id", "production");
future.thenAccept(count -> {
System.out.println("Loaded " + count + " secrets");
});
// Async secrets retrieval
client.exportSecretsAsMapAsync("project-id", "production")
.thenAccept(secrets -> {
System.out.println(secrets.get("DATABASE_URL"));
});Caching
Enable caching for better performance in high-throughput applications:
import java.time.Duration;
KeyEnv client = KeyEnv.builder()
.token(System.getenv("KEYENV_TOKEN"))
.cacheTtl(Duration.ofMinutes(5))
.build();
// First call fetches from API
client.exportSecrets("project-id", "production");
// Subsequent calls within TTL use cache
client.exportSecrets("project-id", "production");
// Clear cache when needed
client.clearCache("project-id", "production");
client.clearAllCache();Error Handling
import dev.keyenv.KeyEnv;
import dev.keyenv.KeyEnvException;
try {
var secret = client.getSecret("project-id", "production", "MISSING_KEY");
} catch (KeyEnvException e) {
System.err.println("Error " + e.getStatus() + ": " + e.getMessage());
if (e.getStatus() == 401) {
System.err.println("Invalid or expired token");
} else if (e.getStatus() == 403) {
System.err.println("Access denied");
} else if (e.getStatus() == 404) {
System.err.println("Secret not found");
}
}API Reference
Constructor Options (Builder)
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
token | String | Yes | - | Service token |
timeout | Duration | No | 30s | Request timeout |
cacheTtl | Duration | No | 0 | Cache TTL (0 disables) |
baseUrl | String | No | https://api.keyenv.dev | API base URL |
Methods
| Method | Description |
|---|---|
getCurrentUser() | Get current user/token info |
listProjects() | List all accessible projects |
getProject(id) | Get project with environments |
listEnvironments(projectId) | List environments in a project |
listSecrets(projectId, env) | List secret keys (no values) |
exportSecrets(projectId, env) | Export secrets with values |
exportSecretsAsMap(projectId, env) | Export as key-value map |
getSecret(projectId, env, key) | Get single secret |
setSecret(projectId, env, key, value) | Create or update secret |
deleteSecret(projectId, env, key) | Delete secret |
bulkImport(projectId, env, secrets, options) | Bulk import secrets |
loadEnv(projectId, env) | Load secrets into System properties |
generateEnvFile(projectId, env) | Generate .env file content |
listPermissions(projectId, env) | List permissions for an environment |
setPermission(projectId, env, userId, role) | Set user's permission |
deletePermission(projectId, env, userId) | Delete user's permission |
getMyPermissions(projectId) | Get current user's permissions |
getProjectDefaults(projectId) | Get default permissions |
setProjectDefaults(projectId, defaults) | Set default permissions |
Examples
Spring Boot Application
import dev.keyenv.KeyEnv;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import jakarta.annotation.PostConstruct;
@SpringBootApplication
public class Application {
@PostConstruct
public void loadSecrets() {
String token = System.getenv("KEYENV_TOKEN");
if (token != null) {
KeyEnv client = KeyEnv.create(token);
client.loadEnv(System.getenv("KEYENV_PROJECT"), "production");
}
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}Micronaut Application
import dev.keyenv.KeyEnv;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.context.event.StartupEvent;
import jakarta.inject.Singleton;
@Singleton
public class SecretsLoader implements ApplicationEventListener<StartupEvent> {
@Override
public void onApplicationEvent(StartupEvent event) {
String token = System.getenv("KEYENV_TOKEN");
if (token != null) {
KeyEnv client = KeyEnv.create(token);
int count = client.loadEnv(System.getenv("KEYENV_PROJECT"), "production");
System.out.println("Loaded " + count + " secrets from KeyEnv");
}
}
}Quarkus Application
import dev.keyenv.KeyEnv;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
@Startup
public class SecretsConfig {
@PostConstruct
void loadSecrets() {
String token = System.getenv("KEYENV_TOKEN");
if (token != null) {
KeyEnv client = KeyEnv.create(token);
client.loadEnv(System.getenv("KEYENV_PROJECT"), "production");
}
}
}