Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cmd/blitz/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/observiq/blitz/generator/kubernetes"
"github.com/observiq/blitz/generator/nginx"
gennop "github.com/observiq/blitz/generator/nop"
"github.com/observiq/blitz/generator/okta"
"github.com/observiq/blitz/generator/paloalto"
"github.com/observiq/blitz/generator/postgres"
"github.com/observiq/blitz/generator/winevt"
Expand Down Expand Up @@ -388,6 +389,16 @@ func run(cmd *cobra.Command, args []string) error {
logger.Error("Failed to create File generator", zap.Error(err))
return err
}
case config.GeneratorTypeOkta:
generatorInstance, err = okta.New(
logger,
cfg.Generator.Okta.Workers,
cfg.Generator.Okta.Rate,
)
if err != nil {
logger.Error("Failed to create Okta generator", zap.Error(err))
return err
}
default:
logger.Error("Invalid generator type", zap.String("type", string(cfg.Generator.Type)))
return fmt.Errorf("invalid generator type: %s", cfg.Generator.Type)
Expand Down
35 changes: 26 additions & 9 deletions docker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A Docker Compose setup that runs all Blitz log generators simultaneously and sen
┌─────────────────┐
│ blitz-json │──┐
├─────────────────┤ │
│ blitz-pii │──┤ (10x workers - 37 PII types)
│ blitz-pii │──┤ (37 PII types)
├─────────────────┤ │
│ blitz-winevt │──┤
├─────────────────┤ │
Expand All @@ -20,7 +20,9 @@ A Docker Compose setup that runs all Blitz log generators simultaneously and sen
├─────────────────┤ │
│ blitz-postgres │──┤
├─────────────────┤ │
│ blitz-kubernetes│──┘
│ blitz-kubernetes│──┤
├─────────────────┤ │
│ blitz-okta │──┘
└─────────────────┘
```

Expand Down Expand Up @@ -54,7 +56,7 @@ docker compose -f docker/docker-compose.telemetry-generator.yml up
|----------|---------|-------------|
| `BLITZ_RATE` | `1s` | Log generation rate per generator |
| `BLITZ_WORKERS` | `1` | Number of workers per generator |
| `BLITZ_PII_WORKERS` | `10` | Number of workers for PII generator (10x default for comprehensive testing) |
| `BLITZ_PII_WORKERS` | `1` | Number of workers for PII generator |

### Examples

Expand Down Expand Up @@ -86,15 +88,16 @@ docker compose -f docker/docker-compose.telemetry-generator.yml up -d
| Generator | Log Type | Description |
|-----------|----------|-------------|
| `blitz-json` | JSON | Structured JSON logs |
| `blitz-pii` | PII | JSON logs with 37 PII types (SSN, credit card, email, passport, API keys, JWT, etc.) - runs at 10x rate |
| `blitz-pii` | PII | JSON logs with 37 PII types (SSN, credit card, email, passport, API keys, JWT, etc.) |
| `blitz-winevt` | Windows Event | Windows Event logs in XML format |
| `blitz-palo-alto` | Palo Alto | Firewall syslog entries |
| `blitz-apache-common` | Apache Common | Apache Common Log Format (CLF) |
| `blitz-apache-common` | Apache Common | Apache Common Log Format (CLF) with security attack patterns |
| `blitz-apache-combined` | Apache Combined | Apache Combined Log Format with referer/user-agent |
| `blitz-apache-error` | Apache Error | Apache error log format |
| `blitz-nginx` | NGINX | NGINX Combined Log Format |
| `blitz-postgres` | PostgreSQL | PostgreSQL database logs |
| `blitz-kubernetes` | Kubernetes | Container logs in CRI-O format |
| `blitz-nginx` | NGINX | NGINX Combined Log Format with security attack patterns |
| `blitz-postgres` | PostgreSQL | PostgreSQL database logs with security events |
| `blitz-kubernetes` | Kubernetes | Container logs in CRI-O format with security events |
| `blitz-okta` | Okta | Okta System Log events (authentication, security, lifecycle) |

## Running Individual Generators

Expand All @@ -117,7 +120,21 @@ docker compose -f docker/docker-compose.telemetry-generator.yml down
| File | Description |
|------|-------------|
| `docker-compose.telemetry-generator.yml` | Docker Compose configuration |
| `collector-config.yaml` | Bindplane Agent OTLP receiver configuration |

## Building Local Image

To build and use a local image instead of `ghcr.io/observiq/blitz:latest`:

```bash
# Build the binary
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o package/blitz ./cmd/blitz

# Build the Docker image
docker build -t blitz:local -f package/Dockerfile package/

# Update compose file to use local image
sed -i 's|ghcr.io/observiq/blitz:latest|blitz:local|g' docker/docker-compose.telemetry-generator.yml
```

## Kubernetes Deployment

Expand Down
38 changes: 0 additions & 38 deletions docker/collector-config.yaml

This file was deleted.

19 changes: 17 additions & 2 deletions docker/docker-compose.telemetry-generator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
# Optional environment variables:
# - BLITZ_RATE: Log generation rate (default: 1s)
# - BLITZ_WORKERS: Workers per generator (default: 1)
# - BLITZ_PII_WORKERS: PII workers (default: 1)

x-blitz-common: &blitz-common
image: ghcr.io/observiq/blitz:latest
Expand Down Expand Up @@ -43,6 +44,8 @@ services:
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
volumes:
- collector-data:/etc/otel
networks:
- telemetry-net

Expand All @@ -58,13 +61,12 @@ services:
BLITZ_OUTPUT_OTLPGRPC_PORT: "4317"

# PII Log Generator (JSON with comprehensive PII data - 37 sensitive data types)
# Runs at 10x rate compared to other generators for thorough PII testing
blitz-pii:
<<: *blitz-common
environment:
BLITZ_GENERATOR_TYPE: json
BLITZ_GENERATOR_JSON_TYPE: pii
BLITZ_GENERATOR_JSON_WORKERS: ${BLITZ_PII_WORKERS:-10}
BLITZ_GENERATOR_JSON_WORKERS: ${BLITZ_PII_WORKERS:-1}
BLITZ_GENERATOR_JSON_RATE: ${BLITZ_RATE:-1s}
BLITZ_OUTPUT_TYPE: otlp-grpc
BLITZ_OUTPUT_OTLPGRPC_HOST: bdot-collector
Expand Down Expand Up @@ -158,7 +160,20 @@ services:
BLITZ_OUTPUT_OTLPGRPC_HOST: bdot-collector
BLITZ_OUTPUT_OTLPGRPC_PORT: "4317"

# Okta System Log Generator
blitz-okta:
<<: *blitz-common
environment:
BLITZ_GENERATOR_TYPE: okta
BLITZ_GENERATOR_OKTA_WORKERS: ${BLITZ_WORKERS:-1}
BLITZ_GENERATOR_OKTA_RATE: ${BLITZ_RATE:-1s}
BLITZ_OUTPUT_TYPE: otlp-grpc
BLITZ_OUTPUT_OTLPGRPC_HOST: bdot-collector
BLITZ_OUTPUT_OTLPGRPC_PORT: "4317"

networks:
telemetry-net:
driver: bridge

volumes:
collector-data:
54 changes: 54 additions & 0 deletions docs/generator/okta.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Okta System Log Generator

The Okta generator creates synthetic Okta System Log events in JSON format. It produces realistic authentication, security, user lifecycle, and administrative events that match the Okta System Log API schema.

## Description

The Okta System Log format is a JSON structure that includes event type, actor, client context, outcome, target, and security context fields. The generator produces events across multiple categories: authentication (login, SSO, MFA), security threats (brute force, credential stuffing, impossible travel), user lifecycle (create, activate, suspend, delete), password operations, application and group membership changes, policy management, and administrative actions.

## Example Logs

```json
{"uuid":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","published":"2025-11-10T21:11:47.123Z","eventType":"user.session.start","version":"0","severity":"INFO","displayMessage":"User login to Okta","actor":{"id":"00u1234567890","type":"User","alternateId":"john.smith@example.com","displayName":"John Smith"},"client":{"userAgent":{"rawUserAgent":"Mozilla/5.0...","os":"Unknown","browser":"UNKNOWN"},"zone":"null","device":"Unknown","ipAddress":"192.168.1.100","geographicalContext":{"city":"San Francisco","state":"California","country":"United States","postalCode":"94102","geolocation":{"lat":37.7749,"lon":-122.4194}}},"outcome":{"result":"SUCCESS"},"target":[{"id":"0oa1234567890","type":"AppInstance","alternateId":"slack","displayName":"Slack"}],"transaction":{"type":"WEB","id":"AbCdEfGhIjKlMnOpQrSt","detail":{}},"authenticationContext":{"authenticationProvider":"OKTA_AUTHENTICATION_PROVIDER","credentialProvider":"OKTA_CREDENTIAL_PROVIDER","credentialType":"PASSWORD"},"securityContext":{"asNumber":12345,"asOrg":"example-isp","isp":"Example ISP","domain":"example.com","isProxy":false}}
```

## Configuration

| YAML Path | Flag Name | Environment Variable | Default | Description |
|-----------|-----------|---------------------|---------|-------------|
| `generator.type` | `--generator-type` | `BLITZ_GENERATOR_TYPE` | `nop` | Generator type. Set to `okta` to use this generator. |
| `generator.okta.workers` | `--generator-okta-workers` | `BLITZ_GENERATOR_OKTA_WORKERS` | `1` | Number of Okta generator workers (must be >= 1) |
| `generator.okta.rate` | `--generator-okta-rate` | `BLITZ_GENERATOR_OKTA_RATE` | `1s` | Rate at which logs are generated per worker (duration format) |

## Example Configuration

```yaml
generator:
type: okta
okta:
workers: 5
rate: 100ms
```

## Event Categories

| Category | Event Types | Severity |
|----------|------------|----------|
| Authentication | `user.session.start`, `user.session.end`, `user.authentication.sso`, `user.authentication.auth_via_mfa` | INFO/WARN |
| Security | `security.threat.detected`, `security.request.blocked`, `user.session.impersonation.start` | WARN/ERROR |
| User Lifecycle | `user.lifecycle.create`, `user.lifecycle.activate`, `user.lifecycle.deactivate`, `user.lifecycle.suspend` | INFO/WARN |
| Password | `user.account.update_password`, `user.account.reset_password`, `user.credential.forgot_password` | INFO |
| Application | `app.user_membership.add`, `app.user_membership.remove`, `application.lifecycle.create` | INFO |
| Group | `group.user_membership.add`, `group.user_membership.remove`, `group.lifecycle.create` | INFO |
| Policy | `policy.lifecycle.create`, `policy.lifecycle.update`, `policy.rule.create` | INFO |
| Admin | `user.account.privilege.grant`, `system.api_token.create`, `system.api_token.revoke` | INFO/WARN |

## Metrics

The Okta generator exposes the following metrics:

- **`blitz.generator.logs.generated`** (Counter): Total number of logs generated
- **`blitz.generator.workers.active`** (Gauge): Number of active worker goroutines
- **`blitz.generator.write.errors`** (Counter): Total number of write errors, labeled by `error_type` (`unknown` or `timeout`)

All metrics include a `component` label set to `generator_okta`.
12 changes: 10 additions & 2 deletions generator/apache/apache.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/cenkalti/backoff/v4"
"github.com/observiq/blitz/internal/generator/security"
"github.com/observiq/blitz/output"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
Expand Down Expand Up @@ -266,7 +267,8 @@ func generateRequest(r *rand.Rand) string {
methods := []string{"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"}
method := methods[r.Intn(len(methods))] // #nosec G404

paths := []string{
// Normal paths
normalPaths := []string{
"/api/v1/users",
"/api/v1/orders",
"/health",
Expand All @@ -285,7 +287,13 @@ func generateRequest(r *rand.Rand) string {
"/api/v1/verification",
}

path := paths[r.Intn(len(paths))] // #nosec G404
// 20% chance of generating a security-focused path
var path string
if r.Float64() < 0.20 { // #nosec G404
path = security.RandomAttackPath(r)
} else {
path = normalPaths[r.Intn(len(normalPaths))] // #nosec G404
}

protocols := []string{"HTTP/1.0", "HTTP/1.1", "HTTP/2.0"}
protocol := protocols[r.Intn(len(protocols))] // #nosec G404
Expand Down
Loading