Commit Graph
1063 Commits
Author SHA1 Message Date
f736ec844c fix: sessions table (#11746)
- **fix latest sessions api**
- **fix: sessions phase 1 ui**
- **fix: minor ui issues**

---------

Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-18 19:20:43 +00:00
Subhra264 015f8778a4 fix: check if auth password is empty for ingestion endpoints (#11918) 2026-05-18 14:35:15 +00:00
Subhra264 ccb2f92599 fix: check if user password is empty in the authentication (#11906) 2026-05-18 12:25:39 +00:00
Loakesh Indiran c679698fa5 fix: correct pagination for ORDER BY non-timestamp column in _search_stream (#11654)
## Problem

`ORDER BY <non-timestamp col>` (e.g. `ORDER BY duration DESC`) gave
wrong results and risked OOM because per-partition \`hits_to_skip\`
assumed rows are time-ordered — but the globally k-th row can be in any
partition.

## Solution

Each partition fetches its local top-`k = from+size` rows. A
**TopKHeap** on the leader merges them globally, skips `from`, returns
`size`. Heap is bounded to `k` elements at all times — O(k) memory
regardless of partition count.

**Multi-column ORDER BY** (`ORDER BY duration DESC, _timestamp DESC`) is
fully honored: heap comparison and final sort respect all columns in
order, using secondary columns as tiebreakers.

## Scenario behavior

| Query | Behavior |
|---|---|
| `ORDER BY _timestamp DESC` | Unchanged — per-partition path |
| `ORDER BY duration DESC` | Heap merge path — correct pagination |
| `ORDER BY duration DESC, _timestamp DESC` | Heap merge; ties in
`duration` broken by `_timestamp` |
| `ORDER BY duration DESC` page 2 | Heap collects global top-k, skips
`from`, returns `size` |
| JOIN / subquery / GROUP BY | `is_aggregate=true` → single partition
(unchanged) |
| `ZO_DISABLE_PARTITIONS_FOR_NON_TS_ORDER_BY=true` | Forces 1 partition
(circuit breaker preserved) |
| Partial cache hit + non-ts ORDER BY | TODO — pre-existing bug, no
regression |

## What is NOT changed

- `ORDER BY _timestamp` execution path
- `_search` (non-streaming) — DataFusion handles it correctly
- Aggregate / histogram queries
2026-05-15 09:09:16 +00:00
ea5e0e1102 feat: org level storage configuration (#11614)
This adds supports for configuring storage at org level instead of
installation level in ent and cloud setup.

design at:
https://github.com/openobserve/designs/blob/main/infrastructure/custom-s3-bucket-support/design.md

---------

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 09:33:02 +00:00
Ashish Kolhe 3161d13785 fix: refactor ssrf (#11734) 2026-05-14 08:32:40 +00:00
99fb8e46a2 fix: support cycle in usage (#11547)
This adds support for current cycle for stripe users as period for usage
page

---------

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
2026-05-12 08:17:34 +00:00
Ashish Kolheandgithub-actions[bot] c686b359bf fix: corelation custom groups + settings fixes (cherry-pick from v0.90.0) (#11705)
## Summary
Cherry-picks two correlation fixes from `branch-v0.90.0` to `main`:

- `a077b760c` fix: corelation custom groups (#11662) — adds `group`
field to `FoundGroup` and threads `semantic_groups` through
`calculate_dimension_analytics`
- `211876a97` fix: corelation settings fixes (#11666) — validates
tracked alias IDs against bundled defaults + custom DB groups; sanitizes
payload (drops `service` and orphan IDs) before save

Conflicts resolved by taking v0.90.0 versions (the fixes are the point
of the cherry-pick). Companion PR on o2-enterprise:
openobserve/o2-enterprise#1648 — that PR is currently red because it
depends on the new `FoundGroup.group` field landing here first.

## Test plan
- [ ] CI green (build, unit, playwright)
- [ ] Verify save Identity Config rejects invalid alias IDs but accepts
default + custom IDs
- [ ] Verify `_analytics` endpoint returns `group` category on
FoundGroup

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-11 03:51:39 +00:00
aa98badd80 fix: refactor llm attribute trace (#11626)
- **fix: llm insights tab**
- **remove custom attributes and use gen ai spec**

---------

Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-05-10 03:38:14 +00:00
Ashish Kolheandgithub-actions[bot] 30991ca2e1 fix: corelation fixes (#11646) (#11649)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-07 12:29:20 +00:00
Ashish Kolhe 3ef50a23e3 fix: field grouping on logs and traces pages (#11576) 2026-05-04 11:39:07 +00:00
Loakesh IndiranandHengfei Yang 379087b550 chore: add sync unit tests (#11588)
## Summary

- Add `#[cfg(test)] mod tests` blocks to ~525 files across all workspace
crates
- Covers: openobserve, infra, config, ingester, wal, flight,
tantivy_utils, cli
- All tests are synchronous (`#[test]` only) — struct defaults, serde
roundtrips, enum variants, pure utility functions
- No async tests, no logic changes — purely additive

---------

Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-05-04 10:38:41 +00:00
c3e03cc6c4 fix: traces list shows blank rows when filtered by duration (#11514)
## Summary

- Replace `SELECT *` Q2 with grouped aggregations so per-trace
enrichment is bounded by N rows instead of total span count.
- Q2a aggregates per `trace_id`: span count, error count, min/max times,
max duration, root span labels (with first-by-timestamp fallback), and
`approx_distinct(service_name)` to gate Q2b.
- Q2b runs only for multi-service traces, returning per-`(trace_id,
service_name)` count and max duration.

## Root cause

When a user filters Traces by Duration, Q2 ran `SELECT * FROM stream
WHERE trace_id IN (...)` and aggregated spans in Rust. For traces with
tens of thousands of spans, the search-service row cap was hit before
every `trace_id` got at least one span back. The un-enriched entries
were still sent to the FE with `spans=[0,0]`, `duration=0`,
`first_event=null` — the blank rows in the screenshot on the issue.

The new Q2a returns one row per `trace_id` (≤ N rows total), so it
cannot trip the row cap. Single-service traces are fully populated from
Q2a alone; only multi-service traces require Q2b. Response shape
(`TraceResponseItem`) is unchanged — `first_event` is now built as a
synthetic `{service_name, operation_name}` object so the FE in
`web/src/composables/useTraces.ts` keeps working unchanged.

Applied to both `get_latest_traces` and `process_latest_traces_stream`.

Closes #11505

## Test plan

- [ ] Open Traces, pick a stream with traces that have many spans (≥10K
spans/trace).
- [ ] Filter by Duration `<= Max value`. Confirm no blank rows; every
row has a service icon, service name, non-zero duration, and a span
count.
- [ ] Single-service stream: confirm the services list under each trace
is correct.
- [ ] Multi-service trace (e.g., a trace that crosses several services):
confirm the per-service breakdown still appears (Q2b path).
- [ ] Sort by duration ASC and DESC.
- [ ] Sort by start_time ASC and DESC.
- [ ] LLM stream: confirm LLM token / cost columns still populate.
- [ ] Pagination: page 1, page 2, page N — every page has fully
populated rows.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Hengfei Yang <undefined@users.noreply.github.com>
2026-04-28 11:51:06 +00:00
20ed7ee5de fix: add usage reporting to license (#11192)
Add support for license v2 and usage reporting

---------

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
2026-04-27 09:09:31 +00:00
b7bc228e49 feat(cloud): support contract subscription (#11336)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: udev <undefined@users.noreply.github.com>
2026-04-27 03:49:50 +00:00
cc466132a7 chore: new home page (#11458)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashish Kolhe <undefined@users.noreply.github.com>
2026-04-25 19:18:21 +00:00
265bcae736 fix: add cache-control header for static assets (#11461)
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 14:57:59 +00:00
Harsh MahajanandShrinath Rao c535fe4402 fix: adding config to disable custom-llm-model-pricing (#11430)
Co-authored-by: Shrinath Rao <shnath@openobserve.ai>
2026-04-24 11:01:28 +05:30
ktx-kirtan 8bdd333a0f Revert "feat: dashboard validation sync from BE" (#11437)
Reverts openobserve/openobserve#11034
2026-04-24 10:38:50 +05:30
aec4a083d9 fix: stack histogram based on stream fields (#11390)
This PR fixes the issue in #11353 

 ## New Env
```sh
name = "ZO_HISTOGRAM_BREAKDOWN_FIELDS",
help = "Comma-separated ordered list of stream fields used for stacked histogram breakdown. First match wins."
default = "severity,log_level,level,status"
```

## Flow Chart

```
UI histogram request (is_ui_histogram = true)
                │
                ▼
    ┌───────────────────────┐
    │  is_multi_stream_search?│
    └───────────────────────┘
         │ yes          │ no
         ▼              ▼
  breakdown_field    stream_names.first()
      = None              │
         │                ▼
         │       infra::schema::get(org, stream, type)
         │                │
         │         ┌──────┴──────┐
         │       fails          ok
         │         │              │
         │         ▼              ▼
         │   breakdown_field   detect_histogram_breakdown_field(fields)
         │       = None              │
         │                   priority scan (case-insensitive):
         │                     1. severity?  ──yes──▶  breakdown_field = severity
         │                     2. log_level? ──yes──▶  breakdown_field = log_level
         │                     3. level?     ──yes──▶  breakdown_field = level
         │                     4. status?    ──yes──▶  breakdown_field = status
         │                     5. none match ──────▶  breakdown_field = None
         │                          │
         └──────────────────────────┘
                          │
                          ▼
          convert_to_histogram_query(sql, streams, multi, breakdown_field)
                          │
             ┌────────────┴────────────┐
          None                      Some(field)
             │                          │
             ▼                          ▼
   SELECT zo_sql_key,        SELECT zo_sql_key,
          zo_sql_num                "field" AS zo_sql_breakdown,
   FROM stream                      zo_sql_num
   WHERE ...              FROM stream
   GROUP BY zo_sql_key    WHERE ...
   ORDER BY zo_sql_key    GROUP BY zo_sql_key, zo_sql_breakdown
                          ORDER BY zo_sql_key
             │                          │
             └────────────┬─────────────┘
                          │
                          ▼
                    execute search
                          │
                          ▼
         Response {
           hits: [{ zo_sql_key, zo_sql_breakdown?, zo_sql_num }]
           histogram_breakdown_field: Option<String>
         }
                          │
             ┌────────────┴────────────┐
          None                      Some(field)
             │                          │
             ▼                          ▼
   generateHistogramData()    generateHistogramData()
   flat map:                  breakdown map:
   key → count                (key, category) → count
   xData / yData              breakdownSeries per category
             │                          │
             ▼                          ▼
     convertLogData()         convertStackedLogData()
     single-series            multi-series stacked
     ECharts options          ECharts options
                              + per-category color (palette)
                              + scrollable legend
             │                          │
             ▼                          ▼
     flat bar chart          stacked bar chart
      (unchanged)            (one color per category)
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: bjp232004 <551527+bjp232004@users.noreply.github.com>
Co-authored-by: Loakesh Indiran <66478092+Loaki07@users.noreply.github.com>
Co-authored-by: Loakesh Indiran <rustyloaki@gmail.com>
2026-04-23 12:06:49 +00:00
Subhra264 232ccf5bf3 fix: map_group_to_role should work even when custom_role is empty (#11408)
- Earlier when map_group_to_role env is enabled, the code flow was
ignoring the map_group_to_role flow when the custom_role was empty
(basically there is no custom role configured in the dex group claim).
This pr fixes this - so no matter whether the custom role is empty or
not, it will go to the map_group_to_role flow (this behaviour was there
earlier, but got broken when the sso claim parser was implemented)
- In the map_group_to_role flow, if the custom role array is empty it
was not adding the sso user to the DEX_DEFAULT_ORG at all even though
the ofga tuple mapping was being done. There is one issue in this pr
though that I just understood, it should add the user to dex_default_org
only when the organizations in the db user create payload is empty
(meaning, if the dex token contains nothing, the user should be added to
dex default org with default dex role). Will fix this shortly.
- When there is new custom org as per the token, it only adds the new
org, but does not remove existing org if there are not present in the
custom group claim returned by the sso claim parser.
2026-04-23 10:40:32 +00:00
78b7b7b622 feat: dashboard validation sync from BE (#11034)
Design at:
https://github.com/openobserve/designs/blob/main/dashboards/dashboard-validation-sync

---------

Co-authored-by: ktx-vaidehi <vaidehi.akhani@kiara.tech>
Co-authored-by: udev <uddhav@openobserve.ai>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Abhay Padamani <undefined@users.noreply.github.com>
2026-04-23 08:13:30 +00:00
Hengfei Yang 8d8352f41a fix: add custom skill support (#11381) 2026-04-23 08:15:45 +08:00
HuaijinandHengfei Yang 61c5826199 chore: code cleanup and add trace_id in logs (#11385)
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-04-22 16:20:32 +00:00
Bhargav 16c542d4d1 fix: Auto run query feature (#11376) 2026-04-22 23:01:08 +08:00
Hengfei Yang 77d376efa2 fix: improve real ip logic (#11378) 2026-04-22 22:56:05 +08:00
Sai Nikhil 78b32b88e3 fix: report folder issues (#11362)
1. search across folders is not working
2. when enabling search across or disabling it calling an api which is
not needed
3. while creating report the add folder is not there
4. while edigint the report user is able to change the folder which is
not consistent with alerts
5. when clicking on any folder if it still loading and user is moved
another folder it shoudl display that folder but it is redirecting user
to the previous folder that was clicked
2026-04-22 12:27:04 +00:00
Harsh Mahajan 3d52f4abd2 chore: LLM observability user-pricing (#10781) 2026-04-22 20:40:12 +08:00
Subhra264 353c58e962 fix: service accounts should not be able to rotate token without rbac (#11359) 2026-04-22 10:15:54 +00:00
Loakesh Indiran ced2f858a7 fix: validate multi-stream SQL join query fields against correct stream schema (#11374)
## Bug

Alert queries using SQL that joins two streams (CTE, direct JOIN,
subquery, UNION) fail
validation with a false `SearchFieldNotFound (20004)` error — even
though the same query
runs fine in Logs UI.

**Example error:**
```
Search field not found: body_type. Field not found in stream schema.
```

The query works in `_search` / `_search_stream` but fails when alerts
calls
`_search?validate=true` or `_search_multi?validate=true` before saving.

---

## Root Cause

`validate_query_fields` in `src/handler/http/request/search/utils.rs`
flattened fields
from **all** streams into one set, then validated every field against
the schema of the
**single primary stream** passed in (`stream_name`).

For a query joining `default` + `k8s_events`, `body_type` (which lives
only in
`k8s_events`) was checked against `default`'s schema — where it doesn't
exist — producing
a false negative.

---

## Behaviour Diagram

### Before (broken)

```
SQL joining "default" + "k8s_events"
                │
                ▼
    Sql::new_with_options() — parses SQL, loads both schemas
                │
                ▼
          ColumnVisitor assigns fields per stream:
          ┌──────────────────────────────────────┐
          │ sql.columns                          │
          │  "default"    → {k8s_pod_name, ...}  │
          │  "k8s_events" → {body_type, ...}     │
          └──────────────────────────────────────┘
                │
                ▼  ← BUG
    flatten ALL streams into one set
    {k8s_pod_name, body_type, event_name, ...}
                │
                ▼
    validate every field against "default" schema only
                │
        ┌───────┴────────┐
        │                │
   k8s_pod_name ✅   body_type ❌  ← only in k8s_events
                         │
                         ▼
            SearchFieldNotFound (20004)
```

### After (fixed)

```
SQL joining "default" + "k8s_events"
                │
                ▼
    Sql::new_with_options() — parses SQL, loads both schemas
                │
                ▼
          ColumnVisitor assigns fields per stream:
          ┌──────────────────────────────────────┐
          │ sql.columns                          │
          │  "default"    → {k8s_pod_name, ...}  │
          │  "k8s_events" → {body_type, ...}     │
          └──────────────────────────────────────┘
                │
                ▼
    find entry where stream_name == "default"
    target_fields = {k8s_pod_name, ...}
                │
                ▼
    validate ONLY "default" fields against "default" schema
                │
        ┌───────┴────────┐
        │                │
   k8s_pod_name ✅   body_type → not in target_fields, skipped ✅
                │
                ▼
              Ok(())
```

---

## Affected Query Shapes

All four patterns hit the same bug — any SQL that produces `sql.columns`
with keys for
more than one stream:

```sql
-- CTE + JOIN
WITH x AS (SELECT ... FROM "default") SELECT b.body_type FROM "k8s_events" b JOIN x ...

-- Direct JOIN
SELECT a.col, b.body_type FROM "default" a JOIN "k8s_events" b ON ...

-- Subquery
SELECT col FROM "default" WHERE id IN (SELECT id FROM "k8s_events")

-- UNION
SELECT col FROM "default" UNION SELECT body_type FROM "k8s_events"
```

---

## How `validate_query_fields` is meant to behave

The function validates **one stream at a time**. The handler calls it
once per stream in
the request — full coverage comes from all the calls combined, not from
a single call.

### `_search_multi` (multi-stream, correct path)

```
_search_multi?validate=true  with streams: ["default", "k8s_events"]
        │
        ├── validate_query_fields(org_id, "default",    sql)
        │       → checks default's fields ✅
        │       → body_type skipped (belongs to k8s_events) ✅
        │
        └── validate_query_fields(org_id, "k8s_events", sql)
                → checks k8s_events' fields including body_type ✅
```

Every stream's fields are validated against their own schema. No false
rejections, no gaps.

### `_search` (single-stream endpoint)

```
_search?validate=true  (primary stream: "default")
        │
        └── validate_query_fields(org_id, "default", sql)
                → checks default's fields ✅
                → body_type skipped (belongs to k8s_events) ✅
                → k8s_events fields: not checked ⚠️
```

`k8s_events` fields go unvalidated at pre-check time. This is a
**pre-existing
limitation**, not introduced by this fix. Runtime execution (DataFusion)
still validates
them — if `body_type` doesn't exist in `k8s_events` at query time, the
query fails then
with a clear error. `_search_multi` is the correct API for multi-stream
queries and
provides full pre-validation coverage.

### `_search_stream`

Never calls `validate_query_fields` — goes straight to execution.
Multi-stream joins
work because DataFusion resolves all streams at runtime.

---

## Fix

Look up the `sql.columns` entry that matches `stream_name` and validate
only that
stream's fields against its own schema. Fields from other streams in the
query are
validated separately when the handler calls `validate_query_fields` for
each stream.

```rust
// Before
let used_fields: HashSet<String> = sql.columns.values().flatten().cloned().collect();

// After
let (target_stream, target_fields) = sql
    .stream_names
    .iter()
    .find(|r| r.stream_name() == stream_name)
    .map(|r| {
        let fields = sql.columns.get(r).cloned().unwrap_or_default();
        (stream_name.to_string(), fields)
    })
    .unwrap_or_else(|| {
        // fallback: aliased or unresolved table — original behaviour
        let fields = sql.columns.values().flatten().cloned().collect();
        (stream_name.to_string(), fields)
    });
```

**File:** `src/handler/http/request/search/utils.rs` —
`validate_query_fields()`

---

## Tests

Added `test_cte_multi_stream_regression` module in `utils.rs`:

- `test_cte_join_cross_stream_field_not_rejected` — regression test for
the exact bug:
sets up `default` schema (no `body_type`) + `k8s_events` schema (has
`body_type`),
runs a CTE join query, asserts `validate_query_fields` returns `Ok(())`
for `default`.
  Fails on old code, passes after fix.
2026-04-22 10:03:01 +00:00
b313248b55 fix: email mismtach cloud (#11340)
This fixes issues
1. on cloud FE would not do case insensitive comparison when checking
user's role
2. in invites flow BE would not do case insensitive comparison for
checking user's invites

---------

Signed-off-by: Yashodhan Joshi <yjdoc2@gmail.com>
Co-authored-by: sai nikhil kethe <nikhil@openobserve.ai>
Co-authored-by: Yashodhan Joshi <yjdoc2@gmail.com>
2026-04-20 15:31:51 +00:00
Hengfei Yang 3bfd7451f0 fix: adjust partition ordering in trace processing (#11334)
Updated the logic for ordering partitions based on the SQL order
expression. If the expression is "zo_sql_timestamp DESC", partitions
remain unchanged. For "zo_sql_timestamp ASC", partitions are reversed.
For other fields, a single partition is returned, ensuring compatibility
with the new ordering requirements.
2026-04-20 12:06:47 +00:00
ByteBakerandAshish Kolhe 907a3c74db fix: simplify _correlate API (#11301)
Co-authored-by: Ashish Kolhe <ashish.j.kolhe@gmail.com>
2026-04-19 10:54:07 +05:30
Subhra264 f45da519f3 feat: introduce api for report folders (#11261)
Ref https://github.com/openobserve/openobserve/issues/11219

Design at: dashboards/REPORT_FOLDER_VIEW_UI.md
2026-04-17 12:00:09 +00:00
udevandBhargav 6f8ea1b772 fix: pagination support for values api (#11237)
Co-authored-by: Bhargav <BJP232004@GMAIL.COM>
2026-04-16 13:03:42 +05:30
Hengfei Yang b266560838 feat: support custom AI tools (#11270) 2026-04-15 20:11:35 +08:00
85d261b5d0 fix: vulnerability scan fixes (#11249)
| # | Severity | Category | File |
| :--- | :--- | :--- | :--- |
| 1 | **High** | SSRF bypass (IPv6) | `ssrf_guard.rs` |
| 2 | **High** | SSRF bypass (retry) | `enrichment_table/mod.rs` |
| 3 | **High** | SSRF defense-in-depth | `alert.rs` |
| 4 | **Critical** | CORS + credentials | `router/mod.rs` |
| 5 | **Critical** | SQL Injection | `postgres.rs`, `sqlite.rs` |
| 6 | **High** | Privilege escalation (token) | `users.rs` |
| 7 | **Medium** | Panic/DoS | `users.rs` |
| 8 | **Low** | Integer overflow | `alerts/mod.rs` |
| 9 | **Medium** | XSS | `alertSummaryGenerator.ts`, `colorizeQuery.ts`
|
| 10 | **Medium** | Credential exposure in logs | `validator.rs`,
`organization.rs`, `users.rs` |

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Shrinath Rao <shnath@openobserve.ai>
Co-authored-by: Prabhat Sharma <hi.prabhat@gmail.com>
2026-04-14 07:22:11 +00:00
Ashish Kolheandgithub-actions[bot] 2ee44808c0 fix: fga for eval templates (#11238)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-13 06:35:27 +00:00
ByteBaker 58a0297b96 fix: SRE SA auth for MCP (#11228)
- fix incidents not correlating for alert ID
- SRE SA no more visible in other screens than main SA list
- SreAgent role cannot be assigned to any other user now
- regular user now working for MCP
2026-04-10 14:41:25 +00:00
Subhra264 938347df85 fix: db email instead of token email, should be used for UserEmail and openfga check (#11226)
When validating access token, we should use the email returned from db
query to do `check_permissions` rbac function call. Reason is, in
openfga db, we store the same user email as stored in the openobserve
db. Hence, all the permission is supposed to be evaluated against the
same email stored in the db.

The email decoded from token can have any case (upper/lower) as per
user's sso config, so it is important to follow the case stored in the
db created when the user logged in for the first time.
2026-04-10 06:38:37 +00:00
Abhay Padamani 5b71a27729 fix: cross link issue with multi stream (#11200) (#11214)
fix #11200
2026-04-09 10:04:18 +00:00
Subhra264andHengfei Yang 1b09ad6a55 fix: return error if inline attachment type is selected for pdf report (#11188)
PDF report does not support inline attachment type, hence this pr.

---------

Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-04-08 13:10:26 +00:00
a9a9a17d73 feat: MCP 2025-11-25 transport upgrades + pinned tools (#11181)
## Summary
Design at: https://github.com/openobserve/o2-enterprise/issues/1413
- **MCP 2025-11-25 Streamable HTTP transport**: validate
`MCP-Protocol-Version` header (400 on mismatch), return HTTP 202 for
JSON-RPC notifications, add `DELETE /api/{org_id}/mcp` for session
termination
- **Pinned tools**: mark `StreamList`, `StreamSchema`, `SearchSQL`,
`PrometheusRangeQuery`, `GetIncident` with `"pinned": true` in
`x-o2-mcp` extension so they appear directly in `tools/list`

## Test plan

- [x] POST with no `id` field (notification) → 202 Accepted, no body
- [x] POST with wrong `MCP-Protocol-Version` header → 400 Bad Request
- [x] DELETE `/api/{org_id}/mcp` → 204 No Content
- [x] `tools/list` response includes the 5 pinned tools directly
- [x] Pinned tools callable directly via `tools/call name=StreamList`
without `tool_search` first

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Huaijin <haohuaijin@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-08 10:25:30 +00:00
f4d148ea65 fix: evaluations as a tab in traces clean (#10988)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashish Kolhe <undefined@users.noreply.github.com>
2026-04-08 07:02:38 +00:00
7389c5b23e fix: service discovery, incidents, service graph (#11180)
Following fixes and enhancements have been made:

**Service Discovery**:
- default field tracker is now used to distinguish services as well in
absence of a user config, the system works out of box
- UI issues
- incorrect field was displayed when a card in recommendation was
clicked
  - scope/workload selectors were leftover
  - stream based service search

**Incidents**:
- AI Analysis failure now emits a failure event correctly, avoiding
false-positive and preventing UI from getting stuck when a prior
`AIAnalysisBegin` event remained in place
- correlate alerts by alert ID, this was a regression after correlation
revamp, useful for correlation in absence of alert ID
- fix sqlx issue wherein `u64` wasn't supported for sqlite, now turned
into `i64`

**Service graph**:
- now ingests using HTTP bulk API. Was failing since recently moved
service graph daemon to alertmanager, which used internal ingest call,
which was unsupported on alertmanager

- Also add Python 2.0 license support for JS

---------

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: ByteBaker <undefined@users.noreply.github.com>
Co-authored-by: Shrinath Rao <shnath@openobserve.ai>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 11:28:52 +05:30
Hengfei Yang d1a5d8f65b fix: enhance URL validation to block private and loopback IP addresses (#11162) 2026-04-07 07:32:03 +00:00
Subhra264andHengfei Yang f344de6458 fix: do not strip base uri prefix in rum enpoints (#11153)
Fixes #11070 

When `ZO_BASE_URI` is set, the rum endpoints get broken. This is because
when we strip prefix in the `validator_rum` functiom, it checks for
`{base_uri}/v1` endpoint. But axum already strips the nesting path when
the `req_data.uri()` is called.

The routing tree for a sub-path deployment `(base_uri = "/openobserve")`
is:

```
nest("/openobserve", app)          ← outer: strips /openobserve
  └── merge(other_service_routes())
        └── nest("/rum", rum_routes)  ← inner: strips /rum
              └── layer(rum_auth_middleware)  ← middleware runs here
```

Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-04-07 02:51:08 +00:00
ByteBakerandHengfei Yang b948361769 chore: update copyright year to 2026 (#11166)
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-04-07 09:57:53 +08:00
1d3618ad94 chore: system-managed SRE Agent service account provisioning (#11130)
## Summary

Implement automatic provisioning and lifecycle management of
per-organization system service accounts for the AI-powered SRE Agent.
These accounts serve as the identity for RCA (Root Cause Analysis) agent
API interactions and are created automatically for each organization.

## Key Features

### Service Account Provisioning
- Database migration creates SRE Agent accounts for all existing
organizations
- Deterministic email format:
`o2-sre-agent.org-<ORG_ID>@openobserve.internal`
- System accounts are automatically created on organization creation
- Idempotent operations ensure safe re-runs and self-healing

### System Account Protection
- API endpoints prevent modification/deletion of system service accounts
(403 Forbidden)
- User responses include `is_system` flag to identify system accounts
- Protection enforced at HTTP handler layer

### RCA Agent Client Refactoring
- Singleton pattern: global client initialized once at startup
- Per-request user credential forwarding for better audit trails and
scoping
- Lazy initialization: returns None if agent service not configured
- Updated all query methods to accept and forward auth credentials

### Incident Correlation Enhancement
- Query `ServiceIdentityConfig` to get configured semantic dimension
groups
- Extract only `distinguish_by` fields from matched identity sets
- Use parallel correlation execution (Service Discovery + semantic
extraction)
- Improved accuracy by using configured groups instead of fallback label
extraction

### Improved Token Redaction
- Consistent 12-character format: first 4 visible characters + 8
asterisks
- Better security for token display in UI
- Updated tests for new redaction format

## Technical Details

### Database Changes
- New migration:
`m20260331_000001_create_sys_rca_agent_service_accounts`
- Creates accounts with organization and RUM tokens
- Safe pagination (100 orgs at a time) with idempotency checks
- System accounts use role type 6 (SreAgent, distinct from
ServiceAccount)

### Authorization
- System accounts added to OpenFGA with standard org membership tuples
- SRE-specific read-only role for permission control
- Self-healing: runtime ensures OpenFGA state is consistent with
database state

### API Changes
- GET /users: Returns `is_system` and `description` fields
- PUT/DELETE /users: Reject modification/deletion of system accounts

## Test Coverage
- Token redaction tests updated for new format
- System service account protection verified
- User list pagination tested with system accounts

## Feature Flag
This is an enterprise feature gated behind `#[cfg(feature =
"enterprise")]`. System accounts are always created, but RCA integration
only works if the agent service is configured.

## Deployment
- Zero-downtime: migration is additive
- Opt-in for OSS deployments
- Automatic provisioning on upgrade and org creation

---------

Co-authored-by: Shrinath Rao <shnath@openobserve.ai>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
2026-04-06 14:30:20 +00:00
漂流 fbf7283ffc chore: use std instead of once_cell (#11081) 2026-04-06 16:27:16 +08:00