Skip to content

Commit 37ea174

Browse files
authored
Merge branch 'master' into add_project_object
2 parents c81cebd + 3f3a4e8 commit 37ea174

File tree

17 files changed

+101
-65
lines changed

17 files changed

+101
-65
lines changed

.github/workflows/build_wheels.yml

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ jobs:
9797
# There's a `git restore` in here because `make install-go-ci-dependencies` is actually messing up go.mod & go.sum.
9898
run: |
9999
pip install -U pip setuptools wheel twine
100-
make install-protoc-dependencies
101100
make build-ui
102101
git status
103102
git restore go.mod go.sum

Makefile

-3
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,6 @@ test-trino-plugin-locally:
395395
kill-trino-locally:
396396
cd ${ROOT_DIR}; docker stop trino
397397

398-
install-protoc-dependencies:
399-
pip install --ignore-installed protobuf==4.24.0 "grpcio-tools>=1.56.2,<2" mypy-protobuf==3.1.0
400-
401398
# Docker
402399

403400
build-docker: build-feature-server-python-aws-docker build-feature-transformation-server-docker build-feature-server-java-docker

docs/getting-started/components/authz_manager.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -61,24 +61,36 @@ For example, the access token for a client `app` of a user with `reader` role sh
6161
}
6262
```
6363

64-
An example of OIDC authorization configuration is the following:
64+
An example of feast OIDC authorization configuration on the server side is the following:
6565
```yaml
6666
project: my-project
6767
auth:
6868
type: oidc
6969
client_id: _CLIENT_ID__
70-
client_secret: _CLIENT_SECRET__
71-
realm: _REALM__
7270
auth_discovery_url: _OIDC_SERVER_URL_/realms/master/.well-known/openid-configuration
7371
...
7472
```
7573

76-
In case of client configuration, the following settings must be added to specify the current user:
74+
In case of client configuration, the following settings username, password and client_secret must be added to specify the current user:
7775
```yaml
7876
auth:
77+
type: oidc
7978
...
8079
username: _USERNAME_
8180
password: _PASSWORD_
81+
client_secret: _CLIENT_SECRET__
82+
```
83+
84+
Below is an example of feast full OIDC client auth configuration:
85+
```yaml
86+
project: my-project
87+
auth:
88+
type: oidc
89+
client_id: test_client_id
90+
client_secret: test_client_secret
91+
username: test_user_name
92+
password: test_password
93+
auth_discovery_url: http://localhost:8080/realms/master/.well-known/openid-configuration
8294
```
8395

8496
### Kubernetes RBAC Authorization

environment-setup.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@ pip install cryptography -U
1313
conda install protobuf
1414
conda install pymssql
1515
pip install -e ".[dev]"
16-
make install-protoc-dependencies PYTHON=3.9
1716
make install-python-ci-dependencies PYTHON=3.9
1817
```
1918
4. start the docker daemon
2019
5. run unit tests:
2120
```bash
2221
make test-python-unit
23-
```
22+
```

pyproject.toml

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
[build-system]
22
requires = [
3+
"grpcio-tools>=1.56.2,<2",
4+
"grpcio>=1.56.2,<2",
5+
"mypy-protobuf==3.1",
6+
"protobuf==4.24.0",
7+
"pybindgen==0.22.0",
38
"setuptools>=60",
4-
"wheel",
59
"setuptools_scm>=6.2",
6-
"grpcio",
7-
"grpcio-tools>=1.47.0",
8-
"mypy-protobuf==3.1",
9-
"protobuf>=4.24.0,<5.0.0",
1010
"sphinx!=4.0.0",
11+
"wheel",
1112
]
1213
build-backend = "setuptools.build_meta"
1314

sdk/python/feast/permissions/auth_model.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Literal, Optional
1+
from typing import Literal
22

33
from feast.repo_config import FeastConfigBaseModel
44

@@ -10,10 +10,12 @@ class AuthConfig(FeastConfigBaseModel):
1010
class OidcAuthConfig(AuthConfig):
1111
auth_discovery_url: str
1212
client_id: str
13-
client_secret: Optional[str] = None
13+
14+
15+
class OidcClientAuthConfig(OidcAuthConfig):
1416
username: str
1517
password: str
16-
realm: str = "master"
18+
client_secret: str
1719

1820

1921
class NoAuthConfig(AuthConfig):

sdk/python/feast/permissions/client/auth_client_manager_factory.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from feast.permissions.auth_model import (
33
AuthConfig,
44
KubernetesAuthConfig,
5-
OidcAuthConfig,
5+
OidcClientAuthConfig,
66
)
77
from feast.permissions.client.auth_client_manager import AuthenticationClientManager
88
from feast.permissions.client.kubernetes_auth_client_manager import (
@@ -15,7 +15,7 @@
1515

1616
def get_auth_client_manager(auth_config: AuthConfig) -> AuthenticationClientManager:
1717
if auth_config.type == AuthType.OIDC.value:
18-
assert isinstance(auth_config, OidcAuthConfig)
18+
assert isinstance(auth_config, OidcClientAuthConfig)
1919
return OidcAuthClientManager(auth_config)
2020
elif auth_config.type == AuthType.KUBERNETES.value:
2121
assert isinstance(auth_config, KubernetesAuthConfig)

sdk/python/feast/permissions/client/oidc_authentication_client_manager.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
import jwt
55
import requests
66

7-
from feast.permissions.auth_model import OidcAuthConfig
7+
from feast.permissions.auth_model import OidcClientAuthConfig
88
from feast.permissions.client.auth_client_manager import AuthenticationClientManager
99
from feast.permissions.oidc_service import OIDCDiscoveryService
1010

1111
logger = logging.getLogger(__name__)
1212

1313

1414
class OidcAuthClientManager(AuthenticationClientManager):
15-
def __init__(self, auth_config: OidcAuthConfig):
15+
def __init__(self, auth_config: OidcClientAuthConfig):
1616
self.auth_config = auth_config
1717

1818
def get_token(self):

sdk/python/feast/permissions/server/utils.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
from feast.permissions.auth.oidc_token_parser import OidcTokenParser
1616
from feast.permissions.auth.token_extractor import TokenExtractor
1717
from feast.permissions.auth.token_parser import TokenParser
18-
from feast.permissions.auth_model import AuthConfig, OidcAuthConfig
18+
from feast.permissions.auth_model import (
19+
AuthConfig,
20+
OidcAuthConfig,
21+
)
1922
from feast.permissions.security_manager import (
2023
SecurityManager,
2124
no_security_manager,

sdk/python/feast/repo_config.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,13 @@
8888
"local": "feast.infra.feature_servers.local_process.config.LocalFeatureServerConfig",
8989
}
9090

91+
ALLOWED_AUTH_TYPES = ["no_auth", "kubernetes", "oidc"]
92+
9193
AUTH_CONFIGS_CLASS_FOR_TYPE = {
9294
"no_auth": "feast.permissions.auth_model.NoAuthConfig",
9395
"kubernetes": "feast.permissions.auth_model.KubernetesAuthConfig",
9496
"oidc": "feast.permissions.auth_model.OidcAuthConfig",
97+
"oidc_client": "feast.permissions.auth_model.OidcClientAuthConfig",
9598
}
9699

97100

@@ -291,11 +294,17 @@ def offline_store(self):
291294
def auth_config(self):
292295
if not self._auth:
293296
if isinstance(self.auth, Dict):
294-
self._auth = get_auth_config_from_type(self.auth.get("type"))(
295-
**self.auth
297+
is_oidc_client = (
298+
self.auth.get("type") == AuthType.OIDC.value
299+
and "username" in self.auth
300+
and "password" in self.auth
301+
and "client_secret" in self.auth
296302
)
303+
self._auth = get_auth_config_from_type(
304+
"oidc_client" if is_oidc_client else self.auth.get("type")
305+
)(**self.auth)
297306
elif isinstance(self.auth, str):
298-
self._auth = get_auth_config_from_type(self.auth.get("type"))()
307+
self._auth = get_auth_config_from_type(self.auth)()
299308
elif self.auth:
300309
self._auth = self.auth
301310

@@ -336,22 +345,21 @@ def _validate_auth_config(cls, values: Any) -> Any:
336345
from feast.permissions.auth_model import AuthConfig
337346

338347
if "auth" in values:
339-
allowed_auth_types = AUTH_CONFIGS_CLASS_FOR_TYPE.keys()
340348
if isinstance(values["auth"], Dict):
341349
if values["auth"].get("type") is None:
342350
raise ValueError(
343-
f"auth configuration is missing authentication type. Possible values={allowed_auth_types}"
351+
f"auth configuration is missing authentication type. Possible values={ALLOWED_AUTH_TYPES}"
344352
)
345-
elif values["auth"]["type"] not in allowed_auth_types:
353+
elif values["auth"]["type"] not in ALLOWED_AUTH_TYPES:
346354
raise ValueError(
347355
f'auth configuration has invalid authentication type={values["auth"]["type"]}. Possible '
348-
f"values={allowed_auth_types}"
356+
f'values={ALLOWED_AUTH_TYPES}'
349357
)
350358
elif isinstance(values["auth"], AuthConfig):
351-
if values["auth"].type not in allowed_auth_types:
359+
if values["auth"].type not in ALLOWED_AUTH_TYPES:
352360
raise ValueError(
353361
f'auth configuration has invalid authentication type={values["auth"].type}. Possible '
354-
f"values={allowed_auth_types}"
362+
f'values={ALLOWED_AUTH_TYPES}'
355363
)
356364
return values
357365

sdk/python/tests/conftest.py

-1
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,6 @@ def is_integration_test(all_markers_from_module):
471471
client_secret: feast-integration-client-secret
472472
username: reader_writer
473473
password: password
474-
realm: master
475474
auth_discovery_url: KEYCLOAK_URL_PLACE_HOLDER/realms/master/.well-known/openid-configuration
476475
"""
477476
),

sdk/python/tests/integration/feature_repos/repo_configuration.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
)
2929
from feast.infra.feature_servers.local_process.config import LocalFeatureServerConfig
3030
from feast.permissions.action import AuthzedAction
31-
from feast.permissions.auth_model import OidcAuthConfig
31+
from feast.permissions.auth_model import OidcClientAuthConfig
3232
from feast.permissions.permission import Permission
3333
from feast.permissions.policy import RoleBasedPolicy
3434
from feast.repo_config import RegistryConfig, RepoConfig
@@ -447,15 +447,14 @@ class OfflineServerPermissionsEnvironment(Environment):
447447
def setup(self):
448448
self.data_source_creator.setup(self.registry)
449449
keycloak_url = self.data_source_creator.get_keycloak_url()
450-
auth_config = OidcAuthConfig(
450+
auth_config = OidcClientAuthConfig(
451451
client_id="feast-integration-client",
452-
client_secret="feast-integration-client-secret",
453-
username="reader_writer",
454-
password="password",
455-
realm="master",
456452
type="oidc",
457453
auth_discovery_url=f"{keycloak_url}/realms/master/.well-known"
458454
f"/openid-configuration",
455+
client_secret="feast-integration-client-secret",
456+
username="reader_writer",
457+
password="password",
459458
)
460459
self.config = RepoConfig(
461460
registry=self.registry,

sdk/python/tests/integration/feature_repos/universal/data_sources/file.py

-4
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,6 @@ def __init__(self, project_name: str, *args, **kwargs):
445445
auth:
446446
type: oidc
447447
client_id: feast-integration-client
448-
client_secret: feast-integration-client-secret
449-
username: reader_writer
450-
password: password
451-
realm: master
452448
auth_discovery_url: {keycloak_url}/realms/master/.well-known/openid-configuration
453449
"""
454450
self.auth_config = auth_config_template.format(keycloak_url=self.keycloak_url)

sdk/python/tests/unit/infra/scaffolding/test_repo_config.py

+34-12
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
KubernetesAuthConfig,
1010
NoAuthConfig,
1111
OidcAuthConfig,
12+
OidcClientAuthConfig,
1213
)
1314
from feast.repo_config import FeastConfigError, load_repo_config
1415

@@ -213,7 +214,6 @@ def test_auth_config():
213214
client_secret: test_client_secret
214215
username: test_user_name
215216
password: test_password
216-
realm: master
217217
auth_discovery_url: http://localhost:8080/realms/master/.well-known/openid-configuration
218218
registry: "registry.db"
219219
provider: local
@@ -235,7 +235,6 @@ def test_auth_config():
235235
client_secret: test_client_secret
236236
username: test_user_name
237237
password: test_password
238-
realm: master
239238
auth_discovery_url: http://localhost:8080/realms/master/.well-known/openid-configuration
240239
registry: "registry.db"
241240
provider: local
@@ -247,7 +246,32 @@ def test_auth_config():
247246
expect_error="invalid authentication type=not_valid_auth_type",
248247
)
249248

250-
oidc_repo_config = _test_config(
249+
oidc_server_repo_config = _test_config(
250+
dedent(
251+
"""
252+
project: foo
253+
auth:
254+
type: oidc
255+
client_id: test_client_id
256+
auth_discovery_url: http://localhost:8080/realms/master/.well-known/openid-configuration
257+
registry: "registry.db"
258+
provider: local
259+
online_store:
260+
path: foo
261+
entity_key_serialization_version: 2
262+
"""
263+
),
264+
expect_error=None,
265+
)
266+
assert oidc_server_repo_config.auth["type"] == AuthType.OIDC.value
267+
assert isinstance(oidc_server_repo_config.auth_config, OidcAuthConfig)
268+
assert oidc_server_repo_config.auth_config.client_id == "test_client_id"
269+
assert (
270+
oidc_server_repo_config.auth_config.auth_discovery_url
271+
== "http://localhost:8080/realms/master/.well-known/openid-configuration"
272+
)
273+
274+
oidc_client_repo_config = _test_config(
251275
dedent(
252276
"""
253277
project: foo
@@ -257,7 +281,6 @@ def test_auth_config():
257281
client_secret: test_client_secret
258282
username: test_user_name
259283
password: test_password
260-
realm: master
261284
auth_discovery_url: http://localhost:8080/realms/master/.well-known/openid-configuration
262285
registry: "registry.db"
263286
provider: local
@@ -268,15 +291,14 @@ def test_auth_config():
268291
),
269292
expect_error=None,
270293
)
271-
assert oidc_repo_config.auth["type"] == AuthType.OIDC.value
272-
assert isinstance(oidc_repo_config.auth_config, OidcAuthConfig)
273-
assert oidc_repo_config.auth_config.client_id == "test_client_id"
274-
assert oidc_repo_config.auth_config.client_secret == "test_client_secret"
275-
assert oidc_repo_config.auth_config.username == "test_user_name"
276-
assert oidc_repo_config.auth_config.password == "test_password"
277-
assert oidc_repo_config.auth_config.realm == "master"
294+
assert oidc_client_repo_config.auth["type"] == AuthType.OIDC.value
295+
assert isinstance(oidc_client_repo_config.auth_config, OidcClientAuthConfig)
296+
assert oidc_client_repo_config.auth_config.client_id == "test_client_id"
297+
assert oidc_client_repo_config.auth_config.client_secret == "test_client_secret"
298+
assert oidc_client_repo_config.auth_config.username == "test_user_name"
299+
assert oidc_client_repo_config.auth_config.password == "test_password"
278300
assert (
279-
oidc_repo_config.auth_config.auth_discovery_url
301+
oidc_client_repo_config.auth_config.auth_discovery_url
280302
== "http://localhost:8080/realms/master/.well-known/openid-configuration"
281303
)
282304

sdk/python/tests/unit/permissions/auth/conftest.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,7 @@ def oidc_config() -> OidcAuthConfig:
7676
return OidcAuthConfig(
7777
auth_discovery_url="https://localhost:8080/realms/master/.well-known/openid-configuration",
7878
client_id=_CLIENT_ID,
79-
client_secret="",
80-
username="",
81-
password="",
82-
realm="",
79+
type="oidc",
8380
)
8481

8582

sdk/python/tests/unit/permissions/test_oidc_auth_client.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from feast.permissions.auth_model import (
66
KubernetesAuthConfig,
77
NoAuthConfig,
8-
OidcAuthConfig,
8+
OidcClientAuthConfig,
99
)
1010
from feast.permissions.client.http_auth_requests_wrapper import (
1111
AuthenticatedRequestsSession,
@@ -21,13 +21,14 @@
2121
MOCKED_TOKEN_VALUE: str = "dummy_token"
2222

2323

24-
def _get_dummy_oidc_auth_type() -> OidcAuthConfig:
25-
oidc_config = OidcAuthConfig(
24+
def _get_dummy_oidc_auth_type() -> OidcClientAuthConfig:
25+
oidc_config = OidcClientAuthConfig(
2626
auth_discovery_url="http://localhost:8080/realms/master/.well-known/openid-configuration",
2727
type="oidc",
2828
username="admin_test",
2929
password="password_test",
3030
client_id="dummy_client_id",
31+
client_secret="client_secret",
3132
)
3233
return oidc_config
3334

0 commit comments

Comments
 (0)