Skip to content

Embedding TinyS3 in your application ​

TinyS3's core is an ordinary Java library — you can run a full S3 endpoint inside any JVM process. The most common use is integration tests that need a real S3 API without containers, but it works just as well as a storage component inside a larger application.

Requires Java 25.

Dependency ​

Published to Maven Central:

kotlin
// Gradle
testImplementation("dev.totis:tiny-s3-lib:<version>")
// or implementation(...) when embedding for real
xml
<!-- Maven -->
<dependency>
  <groupId>dev.totis</groupId>
  <artifactId>tiny-s3-lib</artifactId>
  <version><!-- version --></version>
</dependency>

Minimal server ​

java
import dev.totis.tinys3.S3Server;
import dev.totis.tinys3.auth.Credentials;

S3Server server = new S3Server.Builder()
    .withPort(8000)
    .withCredentials(new Credentials("access-key", "secret-key", "us-east-1"))
    .withStorageDir("storage")
    .build();
server.start();
// ... server.stop() when done

In-memory server for tests ​

Nothing touches disk; perfect for JUnit:

java
class MyS3IntegrationTest {
  private S3Server server;

  @BeforeEach
  void setUp() {
    server = new S3Server.Builder()
        .withPort(9876)
        .withCredentials(new Credentials("test", "test", "us-east-1"))
        .withInMemory()
        .build();
    server.start();
  }

  @AfterEach
  void tearDown() {
    server.stop();
  }

  @Test
  void uploadsAndDownloads() {
    S3Client s3 = S3Client.builder()
        .endpointOverride(URI.create("http://localhost:9876"))
        .credentialsProvider(StaticCredentialsProvider.create(
            AwsBasicCredentials.create("test", "test")))
        .region(Region.US_EAST_1)
        .forcePathStyle(true)
        .build();
    s3.createBucket(b -> b.bucket("test-bucket"));
    // ...
  }
}

Erasure-coded storage ​

Bring the file-system module for fault-tolerant storage:

java
StorageConfig config = StorageConfig.create(
    List.of("/disk1", "/disk2", "/disk3", "/disk4", "/disk5", "/disk6"),
    new ErasureConfig(4, 2, 4096));          // 4 data + 2 parity shards
FileSystem fs = new ErasureCodedFileSystem(config);

S3Server server = new S3Server.Builder()
    .withPort(8000)
    .withCredentials(credentials)
    .withFileSystem(fs)
    .build();

Builder reference ​

MethodPurpose
withPort(int)Listen port
withCredentials(Credentials)Root credential (repeatable for multi-user)
withStorageDir(String) / withInMemory() / withFileSystem(FileSystem)Storage backend
withBaseUrl(String)Advertised endpoint for presigned URLs
withTls(TlsConfig)Native TLS
withSseMasterKey(String)Base64 master key enabling SSE-S3 / SSE-KMS
withLifecycleInterval(Duration) / withLifecycleDisabled()Lifecycle expiration cadence
withAccessLogDeliveryInterval(Duration)S3 access-log delivery cadence
withCorsAllowOrigins(List<String>)Whole-server CORS (development)
withRouter(HttpRouter)Mount extra HTTP routes on the same port
withAuthenticator(S3Authenticator)Replace signature verification entirely
withCredentialSource(CredentialSource)Dynamic credential lookup (this is how IAM plugs in)
withIdentityPolicies(IdentityPolicySource)Per-identity policy enforcement
withCryptoService(CryptoService) / withNoOpCrypto()Encryption provider
withCustomExecutor(ExecutorService)Request executor (defaults to virtual threads)
withFastETag()Cheaper non-MD5 ETags
withTestMode()Enables test-only endpoints (_admin/nuke)
withDisableAuthenticationForTesting()Accept any request (tests only)

Adding IAM ​

The tiny-s3-iam module provides the AWS IAM API and plugs into the builder via withCredentialSource / withIdentityPolicies — see how app's Application.java wires IamService for a complete example.

Notes ​

  • Multipart upload state is tracked in memory regardless of storage backend.
  • The server uses virtual threads by default; one instance handles many concurrent clients.
  • S3Server.stop() shuts down the listener and background schedulers.

TinyS3 is AGPLv3 licensed. Cloudflare and Cloudflare Workers are trademarks of Cloudflare, Inc. Amazon S3 and AWS are trademarks of Amazon.com, Inc. or its affiliates. MinIO is a trademark of MinIO, Inc. They are named only to describe compatibility; totis.ai is not affiliated with, endorsed by, or sponsored by any of them.