NormalizeAllowList enforces max entry limits, collapses typed wildcards, and produces a deterministic, deduplicated allow list. A global wildcard returns early with a single `[*:*]` entry, typed wildcards shadow specific IDs, and the final slice is sorted to keep downstream comparisons stable. When
(inputs []AllowListElement)
| 77 | // input is empty we return an empty (non-nil) slice so callers can differentiate |
| 78 | // between "no restriction" and "not provided" cases. |
| 79 | func NormalizeAllowList(inputs []AllowListElement) ([]AllowListElement, error) { |
| 80 | if len(inputs) == 0 { |
| 81 | return []AllowListElement{}, nil |
| 82 | } |
| 83 | if len(inputs) > maxAllowListEntries { |
| 84 | return nil, xerrors.Errorf("allow_list has %d entries; max allowed is %d", len(inputs), maxAllowListEntries) |
| 85 | } |
| 86 | |
| 87 | // Collapse typed wildcards and drop shadowed IDs |
| 88 | typedWildcard := map[string]struct{}{} |
| 89 | idsByType := map[string]map[string]struct{}{} |
| 90 | for _, e := range inputs { |
| 91 | // Global wildcard short-circuits |
| 92 | if e.Type == policy.WildcardSymbol && e.ID == policy.WildcardSymbol { |
| 93 | return []AllowListElement{AllowListAll()}, nil |
| 94 | } |
| 95 | |
| 96 | if e.ID == policy.WildcardSymbol { |
| 97 | typedWildcard[e.Type] = struct{}{} |
| 98 | continue |
| 99 | } |
| 100 | if idsByType[e.Type] == nil { |
| 101 | idsByType[e.Type] = map[string]struct{}{} |
| 102 | } |
| 103 | idsByType[e.Type][e.ID] = struct{}{} |
| 104 | } |
| 105 | |
| 106 | out := make([]AllowListElement, 0) |
| 107 | for t := range typedWildcard { |
| 108 | out = append(out, AllowListElement{Type: t, ID: policy.WildcardSymbol}) |
| 109 | } |
| 110 | for t, ids := range idsByType { |
| 111 | if _, ok := typedWildcard[t]; ok { |
| 112 | continue |
| 113 | } |
| 114 | for id := range ids { |
| 115 | out = append(out, AllowListElement{Type: t, ID: id}) |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | sort.Slice(out, func(i, j int) bool { |
| 120 | if out[i].Type == out[j].Type { |
| 121 | return out[i].ID < out[j].ID |
| 122 | } |
| 123 | return out[i].Type < out[j].Type |
| 124 | }) |
| 125 | return out, nil |
| 126 | } |
| 127 | |
| 128 | // UnionAllowLists merges multiple allow lists, returning the set of resources |
| 129 | // permitted by any input. A global wildcard short-circuits the merge. When no |
no test coverage detected