Skip to content

impl prop redaction#2590

Merged
shivamka1 merged 34 commits into
db_v4from
prop-redaction
May 12, 2026
Merged

impl prop redaction#2590
shivamka1 merged 34 commits into
db_v4from
prop-redaction

Conversation

@shivamka1
Copy link
Copy Markdown
Collaborator

@shivamka1 shivamka1 commented Apr 27, 2026

Summary

Introduces PropertyRedactedGraph — a graph view that enforces property
visibility at the data layer — and plumbs it through storage, materialization,
and schema introspection so hidden properties never surface regardless of how
the graph is accessed.

PropertyRedactedGraph view

  • New PropertyRedaction struct with per-entity, per-category restrictions
    (node/edge/graph, temporal properties vs metadata).
  • RedactionArrays precomputes boolean visibility arrays indexed by property
    ID at construction time, giving O(1) lookup. Out-of-range IDs default to
    hidden (previously defaulted to visible).
  • PropertyRedactedGraph<G> wraps any graph view and filters all property
    access through those arrays.
  • exclude_properties(&self, redaction: &PropertyRedaction) added to graph
    views to create a redacted wrapper.

Storage-level filtering

  • temp_prop_rows signature changed to accept Arc<[usize]> of visible
    property IDs. Callers (event_semantics, persistent_semantics) collect
    visible IDs once and pass them down, avoiding a post-filter HashSet on
    the result.
  • node.rows() return type changed to (EventTime, LayerId, Vec<(usize, Prop)>)
    — layer is now included alongside the time and property row.
  • All node history and temporal property APIs now accept an explicit
    layer_ids parameter instead of relying on implicit context.

Materialization and receive_graph

  • materialize_impl updated to call filter_node_prop_row through the view,
    so materialized graphs respect the active redaction.
  • receive_graph resolver now applies PropertyRedactedGraph before
    materialising, preventing hidden properties leaking in the encoded graph
    sent to the client.

Schema introspection

  • NodeSchema::properties_inner and metadata_inner now iterate via
    node_visible_temporal_prop_ids() / node_visible_metadata_ids() instead
    of the raw mapper, so schema() respects property redaction.

GQL resolver changes

  • Added graph_type parameter to the graph() query — allows
    re-interpreting a stored graph through event or persistent semantics at
    query time without changing the stored format.
  • Added require_at_least_read(), apply_access_filter(),
    apply_graph_filter(), and build_redaction() helpers for wiring auth
    policy into resolvers.
  • Added get_graph_with_permissions() on Data to load a graph and apply
    the caller's row filter + property redaction in one step.

Test plan

  • cargo build -p raphtory -p raphtory-graphql compiles clean
  • Unit tests in property_redacted_graph.rs pass
  • pytest python/tests/test_permissions.py — all tests pass including
    test_receive_graph_hidden_node_property,
    test_receive_graph_hidden_node_metadata,
    test_schema_hides_node_property,
    test_schema_hides_node_metadata

Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rust Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: e001ffd Previous: 9823ef7 Ratio
large/1k random edge additions 1485898 ns/iter (± 136386) 658628 ns/iter (± 51943) 2.26
large/1k random edge additions with numeric string input 2054927 ns/iter (± 165105) 876236 ns/iter (± 86855) 2.35
lotr_graph/num_edges 4 ns/iter (± 0) 0 ns/iter (± 0) +∞
lotr_graph/num_nodes 4 ns/iter (± 0) 1 ns/iter (± 0) 4
lotr_graph/graph_latest 3 ns/iter (± 0) 0 ns/iter (± 0) +∞
lotr_graph_materialise/materialize 7497010 ns/iter (± 84665) 1564816 ns/iter (± 35303) 4.79
lotr_graph_window_100/num_nodes 12 ns/iter (± 0) 5 ns/iter (± 0) 2.40
lotr_graph_window_100_materialise/materialize 7876461 ns/iter (± 96397) 1669150 ns/iter (± 10700) 4.72
lotr_graph_window_10/has_node_existing 132 ns/iter (± 10) 62 ns/iter (± 11) 2.13
lotr_graph_window_10/iterate nodes 26861 ns/iter (± 53) 11339 ns/iter (± 40) 2.37
lotr_graph_window_10/iterate_exploded_edges 312150 ns/iter (± 789) 155788 ns/iter (± 1001) 2.00
lotr_graph_window_10_materialise/materialize 3323941 ns/iter (± 36612) 971980 ns/iter (± 4278) 3.42
lotr_graph_subgraph_10pc/num_nodes 12 ns/iter (± 0) 4 ns/iter (± 0) 3
lotr_graph_subgraph_10pc_materialise/materialize 1730096 ns/iter (± 80703) 334634 ns/iter (± 1287) 5.17
lotr_graph_subgraph_10pc_windowed/has_node_existing 137 ns/iter (± 11) 62 ns/iter (± 14) 2.21
lotr_graph_subgraph_10pc_windowed/iterate nodes 4737 ns/iter (± 133) 1365 ns/iter (± 3) 3.47
lotr_graph_subgraph_10pc_windowed_materialise/materialize 952157 ns/iter (± 15992) 230399 ns/iter (± 2617) 4.13
lotr_graph_window_50_layered/num_edges_temporal 148213 ns/iter (± 2715) 70121 ns/iter (± 7586) 2.11
lotr_graph_window_50_layered/has_node_existing 407 ns/iter (± 20) 129 ns/iter (± 12) 3.16
lotr_graph_window_50_layered/iterate nodes 67050 ns/iter (± 734) 19308 ns/iter (± 47) 3.47
lotr_graph_window_50_layered/graph_latest 78066 ns/iter (± 1111) 36649 ns/iter (± 916) 2.13
lotr_graph_window_50_layered_materialise/materialize 30337800 ns/iter (± 126385) 3488825 ns/iter (± 24948) 8.70
lotr_graph_persistent_window_50_layered/num_edges_temporal 649546 ns/iter (± 7829) 192686 ns/iter (± 1569) 3.37
lotr_graph_persistent_window_50_layered/has_node_existing 481 ns/iter (± 262) 174 ns/iter (± 83) 2.76
lotr_graph_persistent_window_50_layered/iterate nodes 94110 ns/iter (± 1289) 35886 ns/iter (± 191) 2.62
lotr_graph_persistent_window_50_layered/iterate_exploded_edges 3553463 ns/iter (± 9843) 1659940 ns/iter (± 19402) 2.14
lotr_graph_persistent_window_50_layered_materialise/materialize 51854230 ns/iter (± 678548) 5298035 ns/iter (± 147912) 9.79
lotr_graph/proto_encode 7971652 ns/iter (± 174829) 1157897 ns/iter (± 73709) 6.88

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Copy Markdown
Collaborator

@ljeub-pometry ljeub-pometry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Some minor structural changes needed on the GraphQL side to avoid unnecessarily breaking filter composability
  • Graph-level properties and metadata should be redactable (can be a different PR as it is additive)
  • Expose property/metadata removal as part of GraphViewOps for rust/python for use with materialize

Comment thread python/tests/test_permissions.py Outdated
Comment thread python/tests/test_permissions.py Outdated
Comment thread python/tests/test_permissions.py Outdated
Comment thread raphtory-graphql/src/model/graph/filtering.rs
Comment thread raphtory-graphql/src/model/graph/filtering.rs
Comment thread raphtory-graphql/src/model/mod.rs
Comment thread raphtory-graphql/src/auth_policy.rs Outdated
Comment thread raphtory-graphql/src/auth_policy.rs Outdated
Copy link
Copy Markdown
Collaborator

@ljeub-pometry ljeub-pometry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Graph properties need to be redacted at the graph view level
  • More tests for property redaction in combination with receive graph (make sure materialize works correctly and removes the properties, I'm pretty sure it brings them back right now)
  • For the redacted graph, properties that didn't exist when the filter was created should be redacted by default (they might be in the list of redacted properties)
  • Make sure schema queries are redacted correctly

Comment thread raphtory-graphql/src/model/graph/graph.rs Outdated
Comment thread raphtory-graphql/src/model/graph/graph.rs Outdated
Comment thread raphtory-graphql/src/model/graph/property.rs Outdated
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs
Comment thread raphtory/src/db/graph/views/property_redacted_graph.rs Outdated
Comment thread raphtory/src/db/graph/edge.rs
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory/src/db/api/view/graph.rs Outdated
Comment thread raphtory/src/db/api/view/graph.rs Outdated
Comment thread raphtory/src/db/graph/node.rs Outdated
shivamka1 added 2 commits May 1, 2026 12:55
# Conflicts:
#	docs/reference/graphql/graphql_API.md
#	raphtory-graphql/schema.graphql
#	raphtory-graphql/src/model/graph/property.rs
#	raphtory-graphql/src/model/graph/windowset.rs
#	raphtory-graphql/src/model/mod.rs
#	raphtory-storage/src/graph/nodes/node_storage_ops.rs
Comment thread raphtory-graphql/src/model/mod.rs
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory-graphql/src/model/mod.rs
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory/src/db/api/view/internal/time_semantics/event_semantics.rs Outdated
Comment thread raphtory/tests/db_tests.rs Outdated
shivamka1 and others added 7 commits May 4, 2026 12:48
All graphql(desc) annotations from commit a17131e (Ben Steer) were
dropped when resolving the merge conflict in raphtory-graphql/src/model/mod.rs
during the db_v4 merge (9c715d0). This restores them exactly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory-graphql/src/model/mod.rs Outdated
path: &str,
) -> async_graphql::Result<Option<GqlVectorisedGraph>> {
require_at_least_read(ctx, &self.auth_policy, path)?;
Ok(self
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to ignore the possible filter on the read permissions?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returns None for filtered-access users for now. Embeddings are computed from the full graph and search results cannot be retroactively row-filtered.

}
// Always return null — permission denial is indistinguishable from "not found"
// from the user's perspective. The warning above is the only signal in the logs.
warn!(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graph metadata doesn't respect the read filter (i.e., you will get counts for the unfiltered number of nodes/edges), we need to think about this

Comment thread raphtory-graphql/src/model/mod.rs Outdated
Comment thread raphtory-graphql/src/data.rs Outdated
@shivamka1 shivamka1 merged commit b31dc87 into db_v4 May 12, 2026
21 of 23 checks passed
@shivamka1 shivamka1 deleted the prop-redaction branch May 12, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants