Skip to main content

Execution Context

ExecutionContext provides correlation IDs and traceability metadata for all TealTiger operations.

Overview

Every request should have an ExecutionContext that flows through:
  • TealEngine → TealGuard → TealCircuit → TealAudit
This enables:
  • Distributed tracing across services
  • Audit log correlation for investigations
  • Request attribution for cost and security analysis

Interface

interface ExecutionContext {
  correlation_id: string;
  trace_id?: string;
  span_id?: string;
  actor?: Actor;
  environment?: string;
  metadata?: Record<string, any>;
}

interface Actor {
  id: string;
  type: 'user' | 'service' | 'agent';
  name?: string;
  email?: string;
}

Creating Contexts

Auto-generate correlation ID

import { ExecutionContext } from '@tealtiger/sdk';

const context = ExecutionContext.create({
  actor: {
    id: 'user-123',
    type: 'user',
    email: 'user@example.com'
  },
  environment: 'production'
});

console.log(context.correlation_id); // Auto-generated UUID v4

Provide existing correlation ID

const context = ExecutionContext.create({
  correlation_id: 'existing-correlation-id',
  actor: { id: 'service-456', type: 'service' }
});

From HTTP headers

import { ContextManager } from '@tealtiger/sdk';

// Extract from incoming request
const context = ContextManager.fromHeaders(req.headers);

// Context includes:
// - x-correlation-id (or generates new)
// - x-trace-id (OpenTelemetry compatible)
// - x-span-id

To HTTP headers

// Propagate to downstream services
const headers = ContextManager.toHeaders(context);

await fetch('https://api.example.com', {
  headers: {
    ...headers,
    'Authorization': `Bearer ${token}`
  }
});

Context Propagation

Through TealEngine

const engine = new TealEngine(config);
const context = ExecutionContext.create({ actor });

// Context flows through evaluation
const decision = await engine.evaluate(request, context);

// Decision includes correlation_id
console.log(decision.correlation_id === context.correlation_id); // true

Through TealGuard

const guard = new TealGuard(config);
const context = ExecutionContext.create({ actor });

// Context flows through guardrail checks
const decision = await guard.check(content, context);

console.log(decision.correlation_id); // Same as context

Through TealAudit

const audit = new TealAudit(config);
const context = ExecutionContext.create({ actor });

// Context included in audit events
await audit.log('policy_evaluation', {
  decision,
  context
});

// Query by correlation_id
const events = await audit.query({
  correlation_id: context.correlation_id
});

Distributed Tracing

OpenTelemetry Integration

import { trace } from '@opentelemetry/api';
import { ExecutionContext } from '@tealtiger/sdk';

const span = trace.getActiveSpan();
const spanContext = span?.spanContext();

const context = ExecutionContext.create({
  trace_id: spanContext?.traceId,
  span_id: spanContext?.spanId,
  actor: { id: 'user-123', type: 'user' }
});

// TealTiger decisions are now part of your trace
const decision = await engine.evaluate(request, context);

Multi-Service Correlation

// Service A: Create context
const contextA = ExecutionContext.create({
  actor: { id: 'service-a', type: 'service' }
});

const decisionA = await engineA.evaluate(requestA, contextA);

// Service A → Service B: Propagate context
const headers = ContextManager.toHeaders(contextA);
await fetch('https://service-b/api', { headers });

// Service B: Extract context
const contextB = ContextManager.fromHeaders(req.headers);
const decisionB = await engineB.evaluate(requestB, contextB);

// Both decisions share correlation_id
console.log(decisionA.correlation_id === decisionB.correlation_id); // true

Audit Log Correlation

Query by correlation ID

const context = ExecutionContext.create({ actor });

// Make multiple requests with same context
await engine.evaluate(request1, context);
await guard.check(content, context);
await circuit.execute(operation, context);

// Query all events for this request
const events = await audit.query({
  correlation_id: context.correlation_id
});

// Events include:
// - policy_evaluation
// - guardrail_check
// - circuit_execution

Investigation Workflow

// User reports issue with request
const correlation_id = 'user-reported-correlation-id';

// Retrieve all events for investigation
const events = await audit.query({ correlation_id });

events.forEach(event => {
  console.log(`${event.timestamp}: ${event.event_type}`);
  console.log(`  Decision: ${event.decision?.action}`);
  console.log(`  Reason: ${event.decision?.reason}`);
});

Actor Attribution

User Attribution

const context = ExecutionContext.create({
  actor: {
    id: 'user-123',
    type: 'user',
    email: 'user@example.com',
    name: 'John Doe'
  }
});

// All decisions and audit events attributed to user
const decision = await engine.evaluate(request, context);

Service Attribution

const context = ExecutionContext.create({
  actor: {
    id: 'payment-service',
    type: 'service',
    name: 'Payment Processing Service'
  },
  environment: 'production'
});

// Cost and security events attributed to service
const decision = await engine.evaluate(request, context);

Agent Attribution

const context = ExecutionContext.create({
  actor: {
    id: 'customer-support-agent',
    type: 'agent',
    name: 'Customer Support Agent v2.1'
  }
});

// Agent behavior tracked for governance
const decision = await engine.evaluate(request, context);

Environment Context

const context = ExecutionContext.create({
  actor,
  environment: 'production', // or 'staging', 'development'
  metadata: {
    region: 'us-east-1',
    deployment: 'blue',
    version: 'v2.3.1'
  }
});

// Environment-specific policy modes
const engine = new TealEngine({
  mode: {
    default: PolicyMode.ENFORCE,
    environment_overrides: {
      'development': PolicyMode.REPORT_ONLY,
      'staging': PolicyMode.MONITOR,
      'production': PolicyMode.ENFORCE
    }
  }
});

Best Practices

Always Create Context

// ❌ Bad: No context
const decision = await engine.evaluate(request);

// ✅ Good: Always provide context
const context = ExecutionContext.create({ actor });
const decision = await engine.evaluate(request, context);

Propagate Context

// ❌ Bad: Create new context for each operation
const context1 = ExecutionContext.create({ actor });
await engine.evaluate(request, context1);

const context2 = ExecutionContext.create({ actor }); // Different correlation_id!
await guard.check(content, context2);

// ✅ Good: Reuse same context
const context = ExecutionContext.create({ actor });
await engine.evaluate(request, context);
await guard.check(content, context);

Extract from Headers

// ❌ Bad: Ignore incoming correlation ID
const context = ExecutionContext.create({ actor });

// ✅ Good: Preserve correlation ID from upstream
const context = ContextManager.fromHeaders(req.headers);
if (!context.actor) {
  context.actor = extractActorFromAuth(req);
}

Performance

Context operations are designed to be fast:
  • Context creation: < 0.1ms (UUID generation)
  • Context propagation: < 0.5ms (object passing)
  • Header conversion: < 0.2ms (string serialization)