KeyEnvKeyEnv
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)

OptionTypeRequiredDefaultDescription
tokenStringYes-Service token
timeoutDurationNo30sRequest timeout
cacheTtlDurationNo0Cache TTL (0 disables)
baseUrlStringNohttps://api.keyenv.devAPI base URL

Methods

MethodDescription
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");
        }
    }
}

On this page