Problem · Graph

Effective Access Control

Learn this problem
MediumSnowflake logoSnowflakeFULLTIMEPHONE SCREEN
See Snowflake hiring insights

Problem statement

You are given n access-control nodes numbered from 0 through n - 1. The arrays allowLists and denyLists have one row per node. Each row contains the permission names that the node directly allows or denies.

Each row [parent, child] in edges means that child inherits access-control entries from parent. The directed graph is acyclic, and a node inherits entries from every ancestor reachable through any parent.

For each node, combine all local and inherited allow entries and all local and inherited deny entries. A deny entry overrides every allow entry for the same permission, regardless of whether either entry is local or inherited. Therefore, a permission is effective exactly when it appears in the combined allow set and does not appear in the combined deny set.

Return one permission list per node in node-index order. Remove duplicates and sort each node's effective permission names lexicographically.

Function

getEffectiveAccess(allowLists: String[][], denyLists: String[][], edges: int[][]) → String[][]

Examples

Example 1

allowLists = [["READ"],["WRITE"],["DEPLOY"]]denyLists = [[],["READ"],[]]edges = [[0,1],[1,2]]return = [["READ"],["WRITE"],["DEPLOY","WRITE"]]

Node 1 inherits READ but directly denies it. Node 2 inherits both the allow and the deny, so READ remains excluded while WRITE and DEPLOY are effective.

Example 2

allowLists = [["READ"],["WRITE"],["AUDIT"],["DEPLOY"]]denyLists = [[],[],["WRITE"],["READ"]]edges = [[0,2],[1,2],[2,3]]return = [["READ"],["WRITE"],["AUDIT","READ"],["AUDIT","DEPLOY"]]

Node 2 inherits from two parents and denies inherited WRITE. Node 3 inherits that deny and directly denies READ, leaving AUDIT and DEPLOY.

Example 3

allowLists = [["A","B"],["B","C"],[],["D"]]denyLists = [["B"],[],["C"],[]]edges = [[0,2],[1,2],[2,3]]return = [["A"],["B","C"],["A"],["A","D"]]

At node 2, inherited deny B and local deny C override all matching allows. Both denies continue to node 3.

Constraints

  • 1 <= allowLists.length = denyLists.length <= 500.
  • 0 <= edges.length <= 5000.
  • Every edge is [parent, child] with valid, distinct node indices.
  • The inheritance graph is a directed acyclic graph.
  • Every permission name is a non-empty ASCII token of at most 30 characters and contains no whitespace.
  • The total number of local allow and deny entries is at most 20000.
  • There are at most 2000 distinct permission names, and the total number of returned permission entries is at most 200000.

More Snowflake problems

drafts saved locally
public String[][] getEffectiveAccess(String[][] allowLists, String[][] denyLists, int[][] edges) {
    // write your code here
}
allowLists[["READ"],["WRITE"],["DEPLOY"]]
denyLists[[],["READ"],[]]
edges[[0,1],[1,2]]
expected[["READ", "WRITE", "DEPLOY", "WRITE"]]
checking account