Skip to content

Commit b05911d

Browse files
committed
NoSQL persistence
1 parent 06533d6 commit b05911d

File tree

444 files changed

+42039
-112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

444 files changed

+42039
-112
lines changed

LICENSE

+3
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ This product includes code from Project Nessie.
304304
* tools/config-docs/generator/src/test/java/tests/smallrye/SomeEnum.java
305305
* tools/config-docs/generator/src/test/java/tests/smallrye/VeryNested.java
306306

307+
Code underneath the components/persistence directory, especially pluggable object types, index related, cache,
308+
atomic commit logic and fundamental persistence implementations.
309+
307310
Copyright: Copyright 2015-2025 Dremio Corporation
308311
Home page: https://projectnessie.org/
309312
License: https://www.apache.org/licenses/LICENSE-2.0

bom/build.gradle.kts

+34
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,40 @@ dependencies {
4343
api(project(":polaris-idgen-impl"))
4444
api(project(":polaris-idgen-spi"))
4545

46+
api(project(":polaris-nodes-api"))
47+
api(project(":polaris-nodes-impl"))
48+
api(project(":polaris-nodes-spi"))
49+
api(project(":polaris-nodes-store"))
50+
51+
api(project(":polaris-realms-api"))
52+
api(project(":polaris-realms-impl"))
53+
api(project(":polaris-realms-spi"))
54+
api(project(":polaris-realms-store"))
55+
56+
api(project(":polaris-authz-api"))
57+
api(project(":polaris-authz-impl"))
58+
api(project(":polaris-authz-spi"))
59+
api(project(":polaris-authz-store"))
60+
61+
api(project(":polaris-persistence-api"))
62+
api(project(":polaris-persistence-impl"))
63+
api(project(":polaris-persistence-benchmark"))
64+
api(project(":polaris-persistence-bridge"))
65+
api(project(":polaris-persistence-cache"))
66+
api(project(":polaris-persistence-cdi-common"))
67+
api(project(":polaris-persistence-cdi-quarkus"))
68+
api(project(":polaris-persistence-cdi-weld"))
69+
api(project(":polaris-persistence-commits"))
70+
api(project(":polaris-persistence-correctness"))
71+
api(project(":polaris-persistence-delegate"))
72+
api(project(":polaris-persistence-index"))
73+
api(project(":polaris-persistence-standalone"))
74+
api(project(":polaris-persistence-testextension"))
75+
api(project(":polaris-persistence-types"))
76+
77+
api(project(":polaris-persistence-inmemory"))
78+
api(project(":polaris-persistence-mongodb"))
79+
4680
api(project(":polaris-config-docs-annotations"))
4781
api(project(":polaris-config-docs-generator"))
4882

build.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ tasks.named<RatTask>("rat").configure {
7272
// Manifest files do not allow comments
7373
excludes.add("tools/version/src/jarTest/resources/META-INF/FAKE_MANIFEST.MF")
7474

75+
excludes.add(
76+
"components/persistence/index/src/testFixtures/resources/org/apache/polaris/persistence/indexes/words.gz"
77+
)
78+
7579
excludes.add("ide-name.txt")
7680
excludes.add("version.txt")
7781
excludes.add(".git")

components/authz/README.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one
3+
or more contributor license agreements. See the NOTICE file
4+
distributed with this work for additional information
5+
regarding copyright ownership. The ASF licenses this file
6+
to you under the Apache License, Version 2.0 (the
7+
"License"); you may not use this file except in compliance
8+
with the License. You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing,
13+
software distributed under the License is distributed on an
14+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
KIND, either express or implied. See the License for the
16+
specific language governing permissions and limitations
17+
under the License.
18+
-->
19+
20+
# AuthZ framework with pluggable privileges
21+
22+
Provides a framework and implementations pluggable privileges and privilege checks.
23+
24+
## Privileges
25+
26+
A privilege is globally identified by its name. Privileges can be inheritable (from its parents) or not. Multiple
27+
privileges can be grouped together to a _composite_ privilege (think: `ALL_DML` having `SELECT`, `INSERT`, `UPDATE` and
28+
`DELETE`) - a composite privilege matches, if all its individual privileges match. Multiple privileges can also be
29+
grouped to an _alternative_ privilege, which matches if any of its individual privileges matches.
30+
31+
Available privileges are provided by one or more `PrivilegeProvider`s, which are discovered at runtime.
32+
Note: currently there is only one `ProvilegeProvider` that plugs in the Polaris privileges.
33+
34+
## ACLs, ACL entries and ACL chains
35+
36+
Each securable object can have its own ACL. ACLs consist of ACL entries, which define the _granted_ and _restricted_
37+
privileges by role name. The the number of roles is technically unbounded and the number of ACL entries can become
38+
quite large.
39+
40+
This framework implements [separation of duties](https://en.wikipedia.org/wiki/Separation_of_duties) ("SoD"), which is a
41+
quite demanded functionality not just by large(r) user organizations. TL;DR _SoD_ allows "security administrators" to
42+
grant and revoke privileges to other users, but not leverage those privileges themselves.
43+
44+
The _effective_ set of privileges for a specific operation performed by a specific caller needs to be computed against
45+
the target objects and their parents. _ACL chains_ are the vehicle to model this hierarchy and let the implementation
46+
compute the set of _effective_ privileges based on the individual ACLs and roles.
47+
48+
Note: Privilege checks and _SoD_ are currently not performed via this framework.
49+
50+
## Jackson support & Storage friendly representation
51+
52+
The persistable types `Acl`, `AclEntry`, and `PrivilegeSet` can all be serialized using Jackson.
53+
54+
As the number of ACL entries can become quite large, space efficient serialization is quite important. The
55+
implementation uses bit-set encoding when serializing `PrivilegeSet`s for persistence.
56+
57+
## Code structure
58+
59+
The code is structured into multiple modules. Consuming code should almost always pull in only the API module.
60+
61+
* `polaris-authz-api` provides the necessary Java interfaces and immutable types.
62+
* `polaris-authz-impl` provides the storage agnostic implementation.
63+
* `polaris-authz-spi` provides the necessary interfaces to provide custom privileges and storage implementation.
64+
* `polaris-authz-store` provides the storage implementation based on `polaris-persistence-api`.

components/authz/api/build.gradle.kts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
plugins {
21+
alias(libs.plugins.jandex)
22+
id("polaris-server")
23+
}
24+
25+
description = "Polaris AuthZ API"
26+
27+
dependencies {
28+
implementation(libs.guava)
29+
30+
implementation(platform(libs.jackson.bom))
31+
implementation("com.fasterxml.jackson.core:jackson-databind")
32+
33+
compileOnly(libs.jakarta.annotation.api)
34+
compileOnly(libs.jakarta.validation.api)
35+
compileOnly(libs.jakarta.inject.api)
36+
compileOnly(libs.jakarta.enterprise.cdi.api)
37+
38+
compileOnly(project(":polaris-immutables"))
39+
annotationProcessor(project(":polaris-immutables", configuration = "processor"))
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.authz.api;
20+
21+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
22+
import jakarta.annotation.Nonnull;
23+
import java.util.Set;
24+
import java.util.function.BiConsumer;
25+
import java.util.function.Consumer;
26+
27+
public interface Acl {
28+
29+
void entriesForRoleIds(
30+
@Nonnull Set<String> roleIds, @Nonnull Consumer<AclEntry> aclEntryConsumer);
31+
32+
void forEach(@Nonnull BiConsumer<String, AclEntry> consumer);
33+
34+
interface AclBuilder {
35+
@CanIgnoreReturnValue
36+
AclBuilder from(@Nonnull Acl instance);
37+
38+
@CanIgnoreReturnValue
39+
AclBuilder addEntry(@Nonnull String roleId, @Nonnull AclEntry entry);
40+
41+
@CanIgnoreReturnValue
42+
AclBuilder removeEntry(@Nonnull String roleId);
43+
44+
/**
45+
* Add, remove or update an {@linkplain AclEntry ACL entry} for a role.
46+
*
47+
* <p>The {@linkplain Consumer consumer} is called with an empty builder, if no ACL entry for
48+
* the role exists, otherwise with a builder constructed from the existing entry. If the given
49+
* {@linkplain Consumer consumer} removes all privileges from the ACL entry, the ACL entry will
50+
* be removed.
51+
*/
52+
@CanIgnoreReturnValue
53+
AclBuilder modify(@Nonnull String roleId, @Nonnull Consumer<AclEntry.AclEntryBuilder> entry);
54+
55+
Acl build();
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.authz.api;
20+
21+
import java.util.Optional;
22+
import org.apache.polaris.immutables.PolarisImmutable;
23+
import org.immutables.value.Value;
24+
25+
/** Container for an {@linkplain Acl ACL} of an individual entity and a pointer to its parent. */
26+
@PolarisImmutable
27+
public interface AclChain {
28+
@Value.Parameter(order = 1)
29+
Acl acl();
30+
31+
@Value.Parameter(order = 2)
32+
Optional<AclChain> parent();
33+
34+
static AclChain aclChain(Acl acl, Optional<AclChain> parent) {
35+
return ImmutableAclChain.of(acl, parent);
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.polaris.authz.api;
20+
21+
import com.fasterxml.jackson.annotation.JsonIgnore;
22+
import com.fasterxml.jackson.annotation.JsonInclude;
23+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
24+
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
25+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
26+
import jakarta.annotation.Nonnull;
27+
import java.util.Collection;
28+
import org.apache.polaris.immutables.PolarisImmutable;
29+
import org.immutables.value.Value;
30+
31+
/**
32+
* An {@link Acl ACL} entry holds the {@linkplain PrivilegeSet sets} of <em>granted</em> and
33+
* <em>restricted</em> ("separation of duties") {@linkplain Privilege privileges}.
34+
*/
35+
@PolarisImmutable
36+
@JsonSerialize(as = ImmutableAclEntry.class)
37+
@JsonDeserialize(as = ImmutableAclEntry.class)
38+
public interface AclEntry {
39+
@Value.Parameter(order = 1)
40+
@Value.Default
41+
// The 'CUSTOM/valueFilter' combination is there to only include non-empty privilege sets
42+
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = PrivilegeSetJsonFilter.class)
43+
default PrivilegeSet granted() {
44+
return PrivilegeSet.emptyPrivilegeSet();
45+
}
46+
47+
@Value.Parameter(order = 2)
48+
@Value.Default
49+
// The 'CUSTOM/valueFilter' combination is there to only include non-empty privilege sets
50+
@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = PrivilegeSetJsonFilter.class)
51+
default PrivilegeSet restricted() {
52+
return PrivilegeSet.emptyPrivilegeSet();
53+
}
54+
55+
@Value.NonAttribute
56+
@JsonIgnore
57+
default boolean isEmpty() {
58+
return granted().isEmpty() && restricted().isEmpty();
59+
}
60+
61+
interface AclEntryBuilder {
62+
@CanIgnoreReturnValue
63+
AclEntryBuilder grant(@Nonnull Collection<? extends Privilege> privileges);
64+
65+
@CanIgnoreReturnValue
66+
AclEntryBuilder grant(@Nonnull Privilege... privileges);
67+
68+
@CanIgnoreReturnValue
69+
AclEntryBuilder grant(@Nonnull Privilege privilege);
70+
71+
@CanIgnoreReturnValue
72+
AclEntryBuilder grant(@Nonnull PrivilegeSet privileges);
73+
74+
@CanIgnoreReturnValue
75+
AclEntryBuilder revoke(@Nonnull Collection<? extends Privilege> privileges);
76+
77+
@CanIgnoreReturnValue
78+
AclEntryBuilder revoke(@Nonnull Privilege... privileges);
79+
80+
@CanIgnoreReturnValue
81+
AclEntryBuilder revoke(@Nonnull Privilege privilege);
82+
83+
@CanIgnoreReturnValue
84+
AclEntryBuilder revoke(@Nonnull PrivilegeSet privileges);
85+
86+
@CanIgnoreReturnValue
87+
AclEntryBuilder restrict(@Nonnull Collection<? extends Privilege> privileges);
88+
89+
@CanIgnoreReturnValue
90+
AclEntryBuilder restrict(@Nonnull Privilege... privileges);
91+
92+
@CanIgnoreReturnValue
93+
AclEntryBuilder restrict(@Nonnull Privilege privilege);
94+
95+
@CanIgnoreReturnValue
96+
AclEntryBuilder restrict(@Nonnull PrivilegeSet privileges);
97+
98+
@CanIgnoreReturnValue
99+
AclEntryBuilder unrestrict(@Nonnull Collection<? extends Privilege> privileges);
100+
101+
@CanIgnoreReturnValue
102+
AclEntryBuilder unrestrict(@Nonnull Privilege... privileges);
103+
104+
@CanIgnoreReturnValue
105+
AclEntryBuilder unrestrict(@Nonnull Privilege privilege);
106+
107+
@CanIgnoreReturnValue
108+
AclEntryBuilder unrestrict(@Nonnull PrivilegeSet privileges);
109+
110+
AclEntry build();
111+
}
112+
}

0 commit comments

Comments
 (0)