Skip to content

Commit 13a591d

Browse files
committed
rename proxy and begin adding open telemetry
1 parent f9c117c commit 13a591d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+503
-80
lines changed

.gcp.env.bak

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SENTRIUS_VERSION=1.0.47
2+
SENTRIUS_SSH_VERSION=1.0.6
3+
SENTRIUS_KEYCLOAK_VERSION=1.0.9
4+
SENTRIUS_AGENT_VERSION=1.0.18

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ analytics/target/**
4242
analytics/target/
4343
dataplane/target/**
4444
dataplane/target/
45-
openai-proxy/target/**
46-
openai-proxy/target/
45+
llm-proxy/target/**
46+
llm-proxy/target/
4747
node/*
4848
node_modules/*
4949
api/node_modules/*
@@ -58,4 +58,4 @@ api/node_modules/*
5858

5959
.settings/*
6060
.env.bak
61-
.gcp.env.bak
61+
cp.env.bak

Dockerfile-jaeger

Whitespace-only changes.

ai-agent/src/main/java/io/sentrius/agent/analysis/agents/verbs/AgentVerbs.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,24 @@ public String promptAgent(Map<String, Object> args) throws ZtatException, IOExce
6565

6666
return llmService.askQuestion(chatRequest);
6767
}
68+
69+
@Verb(name = "justify_operations", description = "Chats with an agent to justify operations.", isAiCallable = false)
70+
public String justifyAgent(Map<String, Object> args) throws ZtatException, IOException {
71+
InputStream is = getClass().getClassLoader().getResourceAsStream("agent-config.yaml");
72+
if (is == null) {
73+
throw new RuntimeException("agent-config.yaml not found on classpath");
74+
}
75+
AgentConfig config = new ObjectMapper(new YAMLFactory()).readValue(is, AgentConfig.class);
76+
77+
log.info("Agent config loaded: {}", config);
78+
PromptBuilder promptBuilder = new PromptBuilder(verbRegistry, config);
79+
var prompt = promptBuilder.buildPrompt();
80+
List<Message> messages = new ArrayList<>();
81+
82+
messages.add(Message.builder().role("system").content(prompt).build());
83+
84+
ChatRequest chatRequest = ChatRequest.builder().model("gpt-3.5-turbo").messages(messages).build();
85+
86+
return llmService.askQuestion(chatRequest);
87+
}
6888
}

ai-agent/src/main/java/io/sentrius/agent/analysis/api/AgentController.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ public ResponseEntity<AgentStatus> getStatus() {
1818
return ResponseEntity.ok(AgentStatus.builder().status("UP").version("1.0.0").health("OK").build());
1919
}
2020

21+
2122
}

api/pom.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,31 @@
189189
<version>3.20.0</version>
190190
<scope>compile</scope>
191191
</dependency>
192+
<!-- OpenTelemetry API + SDK -->
193+
<dependency>
194+
<groupId>io.opentelemetry</groupId>
195+
<artifactId>opentelemetry-api</artifactId>
196+
<version>${opentelem}</version>
197+
</dependency>
198+
<dependency>
199+
<groupId>io.opentelemetry</groupId>
200+
<artifactId>opentelemetry-sdk</artifactId>
201+
<version>${opentelem}</version>
202+
</dependency>
203+
204+
<!-- OpenTelemetry instrumentation for Spring Boot -->
205+
<dependency>
206+
<groupId>io.opentelemetry.instrumentation</groupId>
207+
<artifactId>opentelemetry-spring-boot-starter</artifactId>
208+
<version>${opentelem-springboot}</version>
209+
</dependency>
210+
211+
<!-- Export to OTLP (OpenTelemetry Protocol) -->
212+
<dependency>
213+
<groupId>io.opentelemetry</groupId>
214+
<artifactId>opentelemetry-exporter-otlp</artifactId>
215+
<version>${opentelem}</version>
216+
</dependency>
192217
</dependencies>
193218

194219
<build>

api/src/main/java/io/sentrius/sso/controllers/api/AgentApiController.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.sentrius.sso.core.dto.TerminalLogDTO;
1515
import io.sentrius.sso.core.dto.ztat.ZtatRequestDTO;
1616
import io.sentrius.sso.core.model.security.UserType;
17+
import io.sentrius.sso.core.model.security.enums.ApplicationAccessEnum;
1718
import io.sentrius.sso.core.model.security.enums.SSHAccessEnum;
1819
import io.sentrius.sso.core.model.sessions.SessionLog;
1920
import io.sentrius.sso.core.model.sessions.TerminalLogs;
@@ -126,4 +127,55 @@ public ResponseEntity<?> requestRegistration(
126127
}
127128

128129

130+
@PostMapping("/justify")
131+
@LimitAccess(applicationAccess = {ApplicationAccessEnum.CAN_LOG_IN})
132+
public ResponseEntity<?> justifyOperations(
133+
@RequestHeader("Authorization") String token,
134+
@RequestParam("agentId") String agentId,
135+
@RequestParam("jusitificationId") String jusitificationId,
136+
HttpServletRequest request, HttpServletResponse response) throws SQLException, GeneralSecurityException {
137+
138+
String compactJwt = token.startsWith("Bearer ") ? token.substring(7) : token;
139+
140+
141+
if (!keycloakService.validateJwt(compactJwt)) {
142+
log.warn("Invalid Keycloak token");
143+
return ResponseEntity.status(HttpStatus.SC_UNAUTHORIZED).body("Invalid Keycloak token");
144+
}
145+
146+
var operatingUser = getOperatingUser(request, response );
147+
148+
// Extract agent identity from the JWT
149+
// String agentId = keycloakService.extractAgentId(compactJwt);
150+
151+
if (null == operatingUser) {
152+
log.warn("No operating user found for agent: {}", agentId);
153+
var username = keycloakService.extractUsername(compactJwt);
154+
operatingUser = userService.getUserWithDetails(username);
155+
156+
}
157+
158+
log.info("Received registration request from agent: {} {}", agentId, operatingUser);
159+
// Store the request in the database
160+
var ztatRequest = ztatService.createAgentRequest(agentId, "registration", "register",
161+
ZeroTrustAccessTokenReason.builder().commandNeed("registration call").reasonIdentifier(UUID.randomUUID().toString()).build(),
162+
operatingUser);
163+
ztatRequest = ztrService.addJITRequest(ztatRequest);
164+
165+
// Approve the request if the agent has an active policy ( and it is known and allowed ).
166+
if (atplPolicyService.getPolicy(operatingUser).isPresent()) {
167+
var admin = userService.getUser(UserType.createSystemAdmin().getId());
168+
var approval = ztatService.approveOpsAccessToken(ztatRequest, admin);
169+
170+
return ResponseEntity.ok(Map.of("ztat_token", approval.getToken().toString()));
171+
172+
} else {
173+
log.warn("No active policy found for agent: {}", agentId);
174+
return ResponseEntity.status(428).body(Map.of("ztat_request", ztatRequest.getId()));
175+
}
176+
177+
178+
179+
}
180+
129181
}

api/src/main/resources/application.properties

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,11 @@ management.endpoints.web.exposure.include=health
7878
management.endpoint.health.show-details=always
7979
### change for production environments
8080
https.required=${HTTP_REQUIRED:true}
81+
# Where Spring Boot sends traces
82+
otel.exporter.otlp.endpoint=${OTEL_EXPORTER_OTLP_ENDPOINT:http://localhost:4317}
83+
otel.traces.exporter=otlp
84+
otel.metrics.exporter=none
85+
otel.logs.exporter=none
86+
otel.resource.attributes="service.name=ai-agent"
87+
otel.traces.sampler=always_on
88+
otel.exporter.otlp.timeout=10s

core/pom.xml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,31 @@
229229
<version>3.20.0</version>
230230
<scope>compile</scope>
231231
</dependency>
232+
<!-- OpenTelemetry API + SDK -->
233+
<dependency>
234+
<groupId>io.opentelemetry</groupId>
235+
<artifactId>opentelemetry-api</artifactId>
236+
<version>${opentelem}</version>
237+
</dependency>
238+
<dependency>
239+
<groupId>io.opentelemetry</groupId>
240+
<artifactId>opentelemetry-sdk</artifactId>
241+
<version>${opentelem}</version>
242+
</dependency>
243+
244+
<!-- OpenTelemetry instrumentation for Spring Boot -->
245+
<dependency>
246+
<groupId>io.opentelemetry.instrumentation</groupId>
247+
<artifactId>opentelemetry-spring-boot-starter</artifactId>
248+
<version>${opentelem-springboot}</version>
249+
</dependency>
250+
251+
<!-- Export to OTLP (OpenTelemetry Protocol) -->
252+
<dependency>
253+
<groupId>io.opentelemetry</groupId>
254+
<artifactId>opentelemetry-exporter-otlp</artifactId>
255+
<version>${opentelem}</version>
256+
</dependency>
232257
</dependencies>
233258

234259

core/src/main/java/io/sentrius/sso/core/services/agents/ZeroTrustClientService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ <T> String callPostOnApi(String endpoint, @NonNull String apiEndpoint, T body) t
9292
return response.getBody(); // This is the ZTAT (JWT or opaque token)
9393
} else if (response.getStatusCode() == HttpStatus.PRECONDITION_REQUIRED) {
9494
// we need to get
95-
throw new ZtatException("ZTAT Required");
95+
throw new ZtatException(response.getBody());
9696

9797
} else {
9898
throw new RuntimeException("Failed to obtain ZTAT: " + response.getStatusCode());
@@ -128,7 +128,7 @@ <T> String callGetOnApi(String endpoint, @NonNull String apiEndpoint) throws Zta
128128
return response.getBody(); // This is the ZTAT (JWT or opaque token)
129129
} else if (response.getStatusCode() == HttpStatus.PRECONDITION_REQUIRED) {
130130
// we need to get
131-
throw new ZtatException("ZTAT Required");
131+
throw new ZtatException(response.getBody());
132132

133133
} else {
134134
throw new RuntimeException("Failed to obtain ZTAT: " + response.getStatusCode());

0 commit comments

Comments
 (0)