2025-12-31 · Authensor

AI Agent Safety for Java and Spring Boot

SafeClaw by Authensor provides deny-by-default action gating for Java and Spring Boot AI agents. Every ProcessBuilder.start(), FileInputStream(), and HttpClient.send() call is checked against your YAML policy before execution, preventing unauthorized system access. Install SafeClaw with npx @authensor/safeclaw and integrate it into your Java agent via its local REST API.

Java Agent Risk Surface

Java AI agents running in production have access to the full JVM runtime:

Spring Boot agents are particularly exposed because they often run with the same permissions as the application server. SafeClaw gates each of these operations with 446 tests and hash-chained audit logging.

Installation

npx @authensor/safeclaw

Add the SafeClaw client to your pom.xml:

<!-- Or just use java.net.http.HttpClient directly -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.0</version>
</dependency>

Policy

version: 1
defaultAction: deny

rules:
- action: file.read
path:
glob: "/app/data/**"
decision: allow

- action: file.write
path:
glob: "/app/output/**"
decision: allow

- action: process.exec
command:
startsWith: "mvn"
decision: allow

- action: process.exec
command:
startsWith: "java"
decision: allow

- action: network.request
host:
in: ["api.openai.com", "api.anthropic.com"]
decision: allow

Java Integration

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;

public class SafeClawGate {
private final HttpClient client = HttpClient.newHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
private final String endpoint;

public SafeClawGate() {
this.endpoint = "http://localhost:9800";
}

public record ActionRequest(String action, String path, String command,
String host, String url, String method) {}

public record GateDecision(boolean allowed, String reason) {}

public GateDecision check(ActionRequest req) throws Exception {
String body = mapper.writeValueAsString(req);
HttpRequest httpReq = HttpRequest.newBuilder()
.uri(URI.create(endpoint + "/check"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();

try {
HttpResponse<String> resp = client.send(httpReq,
HttpResponse.BodyHandlers.ofString());
return mapper.readValue(resp.body(), GateDecision.class);
} catch (Exception e) {
// Fail closed
return new GateDecision(false, "SafeClaw unreachable");
}
}
}

Spring Boot Service

import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

@Service
public class SafeAgentService {
private final SafeClawGate gate = new SafeClawGate();

public String readFile(String path) throws Exception {
var decision = gate.check(new SafeClawGate.ActionRequest(
"file.read", path, null, null, null, null
));
if (!decision.allowed()) {
throw new SecurityException("SafeClaw denied: " + decision.reason());
}
return Files.readString(Path.of(path));
}

public String execCommand(String command) throws Exception {
var decision = gate.check(new SafeClawGate.ActionRequest(
"process.exec", null, command, null, null, null
));
if (!decision.allowed()) {
throw new SecurityException("SafeClaw denied: " + decision.reason());
}
Process process = new ProcessBuilder(command.split(" "))
.redirectErrorStream(true)
.start();
return new String(process.getInputStream().readAllBytes());
}
}

SafeClaw logs every gate decision to its hash-chained audit trail. Works with Claude and OpenAI. MIT licensed, zero dependencies.

Cross-References

Try SafeClaw

Action-level gating for AI agents. Set it up in your browser in 60 seconds.

$ npx @authensor/safeclaw