phlo-oauth2-proxy 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: phlo-oauth2-proxy
3
+ Version: 0.2.0
4
+ Summary: oauth2-proxy service plugin for Phlo
5
+ Author-email: Phlo Team <team@phlo.dev>
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/plain
9
+ Requires-Dist: phlo>=0.1.0
10
+ Requires-Dist: pyyaml>=6.0.1
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=7.0; extra == "dev"
13
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
14
+
15
+ oauth2-proxy authentication gateway service plugin for Phlo.
@@ -0,0 +1,26 @@
1
+ # phlo-oauth2-proxy
2
+
3
+ OAuth2/OIDC authentication proxy for Phlo services.
4
+
5
+ Provides a forward-auth gateway using [oauth2-proxy](https://oauth2-proxy.github.io/oauth2-proxy/).
6
+ When paired with `phlo-traefik`, protects `phlo-api` (and optionally other surfaces)
7
+ behind SSO authentication.
8
+
9
+ ## Quick Start
10
+
11
+ 1. Configure your IdP credentials in `.phlo/.env.local`:
12
+
13
+ ```env
14
+ OAUTH2_PROXY_OIDC_ISSUER_URL=https://your-idp.example.com
15
+ OAUTH2_PROXY_CLIENT_ID=your-client-id
16
+ OAUTH2_PROXY_CLIENT_SECRET=your-client-secret
17
+ OAUTH2_PROXY_COOKIE_SECRET=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
18
+ ```
19
+
20
+ 2. Start with the proxy profile:
21
+
22
+ ```bash
23
+ phlo services start --profile proxy
24
+ ```
25
+
26
+ See `docs/setup/security.md` for the full operator walkthrough.
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ build-backend = "setuptools.build_meta"
3
+ requires = [
4
+ "setuptools>=45",
5
+ "wheel",
6
+ ]
7
+
8
+ [project]
9
+ dependencies = [
10
+ "phlo>=0.1.0",
11
+ "pyyaml>=6.0.1",
12
+ ]
13
+ description = "oauth2-proxy service plugin for Phlo"
14
+ name = "phlo-oauth2-proxy"
15
+ requires-python = ">=3.11"
16
+ version = "0.2.0"
17
+
18
+ [[project.authors]]
19
+ email = "team@phlo.dev"
20
+ name = "Phlo Team"
21
+
22
+ [project.entry-points."phlo.plugins.services"]
23
+ oauth2-proxy = "phlo_oauth2_proxy.plugin:Oauth2ProxyServicePlugin"
24
+
25
+ [project.license]
26
+ text = "MIT"
27
+
28
+ [project.optional-dependencies]
29
+ dev = [
30
+ "pytest>=7.0",
31
+ "ruff>=0.1.0",
32
+ ]
33
+
34
+ [project.readme]
35
+ content-type = "text/plain"
36
+ text = "oauth2-proxy authentication gateway service plugin for Phlo."
37
+
38
+ [tool.ruff]
39
+ line-length = 100
40
+ target-version = "py311"
41
+
42
+ [tool.setuptools]
43
+ include-package-data = true
44
+
45
+ [tool.setuptools.package-data]
46
+ phlo_oauth2_proxy = ["service.yaml"]
47
+
48
+ [tool.setuptools.package-dir]
49
+ "" = "src"
50
+
51
+ [tool.setuptools.packages.find]
52
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ """oauth2-proxy authentication gateway for Phlo."""
@@ -0,0 +1,51 @@
1
+ """oauth2-proxy service plugin implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from phlo.plugins import PackageYamlServicePlugin, PluginMetadata
6
+
7
+
8
+ class Oauth2ProxyServicePlugin(PackageYamlServicePlugin):
9
+ """Service plugin for oauth2-proxy authentication gateway.
10
+
11
+ This plugin provides integration with oauth2-proxy, an OAuth2/OIDC
12
+ authentication proxy that implements forward-auth with Traefik.
13
+ It reads service configuration from a bundled service.yaml file
14
+ and exposes standard Phlo plugin metadata.
15
+
16
+ Attributes:
17
+ None
18
+
19
+ Example:
20
+ >>> plugin = Oauth2ProxyServicePlugin()
21
+ >>> metadata = plugin.metadata
22
+ >>> print(metadata.name, metadata.version)
23
+ oauth2-proxy 0.1.0
24
+ >>> definition = plugin.service_definition
25
+
26
+ """
27
+
28
+ @property
29
+ def metadata(self) -> PluginMetadata:
30
+ """Return plugin metadata for the oauth2-proxy service.
31
+
32
+ Returns:
33
+ PluginMetadata: Plugin metadata containing name, version,
34
+ description, author, and tags.
35
+
36
+ Example:
37
+ >>> plugin = Oauth2ProxyServicePlugin()
38
+ >>> meta = plugin.metadata
39
+ >>> meta.name
40
+ 'oauth2-proxy'
41
+ >>> meta.tags
42
+ ['auth', 'proxy', 'oidc']
43
+
44
+ """
45
+ return PluginMetadata(
46
+ name="oauth2-proxy",
47
+ version="0.1.0",
48
+ description="OAuth2/OIDC authentication proxy for Phlo services",
49
+ author="Phlo Team",
50
+ tags=["auth", "proxy", "oidc"],
51
+ )
@@ -0,0 +1,63 @@
1
+ name: oauth2-proxy
2
+ description: OAuth2/OIDC authentication proxy for forward-auth with Traefik
3
+ category: auth
4
+ default: false
5
+ profile: proxy
6
+
7
+ image: quay.io/oauth2-proxy/oauth2-proxy:v7.7.1
8
+
9
+ compose:
10
+ restart: unless-stopped
11
+ labels:
12
+ phlo.metrics.enabled: "false"
13
+ environment:
14
+ OAUTH2_PROXY_HTTP_ADDRESS: "0.0.0.0:4180"
15
+ OAUTH2_PROXY_REVERSE_PROXY: "true"
16
+ OAUTH2_PROXY_SET_XAUTHREQUEST: "true"
17
+ OAUTH2_PROXY_PASS_ACCESS_TOKEN: "false"
18
+ OAUTH2_PROXY_PROVIDER: "${OAUTH2_PROXY_PROVIDER:-oidc}"
19
+ OAUTH2_PROXY_OIDC_ISSUER_URL: "${OAUTH2_PROXY_OIDC_ISSUER_URL}"
20
+ OAUTH2_PROXY_CLIENT_ID: "${OAUTH2_PROXY_CLIENT_ID}"
21
+ OAUTH2_PROXY_CLIENT_SECRET: "${OAUTH2_PROXY_CLIENT_SECRET}"
22
+ OAUTH2_PROXY_COOKIE_SECRET: "${OAUTH2_PROXY_COOKIE_SECRET}"
23
+ OAUTH2_PROXY_COOKIE_SECURE: "${OAUTH2_PROXY_COOKIE_SECURE:-false}"
24
+ OAUTH2_PROXY_REDIRECT_URL: "${OAUTH2_PROXY_REDIRECT_URL:-http://api.phlo.localhost/oauth2/callback}"
25
+ OAUTH2_PROXY_EMAIL_DOMAINS: "${OAUTH2_PROXY_EMAIL_DOMAINS:-*}"
26
+ OAUTH2_PROXY_UPSTREAMS: "static://202"
27
+ OAUTH2_PROXY_SKIP_PROVIDER_BUTTON: "true"
28
+ healthcheck:
29
+ test:
30
+ [
31
+ "CMD",
32
+ "wget",
33
+ "--quiet",
34
+ "--tries=1",
35
+ "--spider",
36
+ "http://127.0.0.1:4180/ping",
37
+ ]
38
+ interval: 30s
39
+ timeout: 5s
40
+ retries: 3
41
+ start_period: 10s
42
+
43
+ env_vars:
44
+ OAUTH2_PROXY_PROVIDER:
45
+ default: oidc
46
+ description: OAuth2 provider type (oidc, google, github, etc.)
47
+ OAUTH2_PROXY_OIDC_ISSUER_URL:
48
+ description: OIDC issuer URL (e.g., https://accounts.google.com)
49
+ OAUTH2_PROXY_CLIENT_ID:
50
+ description: OAuth2 client ID from your identity provider
51
+ OAUTH2_PROXY_CLIENT_SECRET:
52
+ description: OAuth2 client secret (store in .phlo/.env.local)
53
+ OAUTH2_PROXY_COOKIE_SECRET:
54
+ description: Random 32-byte base64 string for cookie encryption (generate with python -c "import secrets; print(secrets.token_urlsafe(32))")
55
+ OAUTH2_PROXY_COOKIE_SECURE:
56
+ default: "false"
57
+ description: Set to true when using HTTPS
58
+ OAUTH2_PROXY_REDIRECT_URL:
59
+ default: http://api.phlo.localhost/oauth2/callback
60
+ description: OAuth2 callback URL (must match IdP config)
61
+ OAUTH2_PROXY_EMAIL_DOMAINS:
62
+ default: "*"
63
+ description: Comma-separated list of allowed email domains (use * for any)
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: phlo-oauth2-proxy
3
+ Version: 0.2.0
4
+ Summary: oauth2-proxy service plugin for Phlo
5
+ Author-email: Phlo Team <team@phlo.dev>
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/plain
9
+ Requires-Dist: phlo>=0.1.0
10
+ Requires-Dist: pyyaml>=6.0.1
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest>=7.0; extra == "dev"
13
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
14
+
15
+ oauth2-proxy authentication gateway service plugin for Phlo.
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/phlo_oauth2_proxy/__init__.py
4
+ src/phlo_oauth2_proxy/plugin.py
5
+ src/phlo_oauth2_proxy/service.yaml
6
+ src/phlo_oauth2_proxy.egg-info/PKG-INFO
7
+ src/phlo_oauth2_proxy.egg-info/SOURCES.txt
8
+ src/phlo_oauth2_proxy.egg-info/dependency_links.txt
9
+ src/phlo_oauth2_proxy.egg-info/entry_points.txt
10
+ src/phlo_oauth2_proxy.egg-info/requires.txt
11
+ src/phlo_oauth2_proxy.egg-info/top_level.txt
12
+ tests/test_oauth2_proxy_plugin.py
@@ -0,0 +1,2 @@
1
+ [phlo.plugins.services]
2
+ oauth2-proxy = phlo_oauth2_proxy.plugin:Oauth2ProxyServicePlugin
@@ -0,0 +1,6 @@
1
+ phlo>=0.1.0
2
+ pyyaml>=6.0.1
3
+
4
+ [dev]
5
+ pytest>=7.0
6
+ ruff>=0.1.0
@@ -0,0 +1 @@
1
+ phlo_oauth2_proxy
@@ -0,0 +1,42 @@
1
+ """Tests for oauth2-proxy service plugin."""
2
+
3
+ from phlo_oauth2_proxy.plugin import Oauth2ProxyServicePlugin
4
+
5
+
6
+ def test_oauth2_proxy_service_definition():
7
+ """Validate oauth2-proxy service metadata in compose definition."""
8
+ plugin = Oauth2ProxyServicePlugin()
9
+ defn = plugin.service_definition
10
+
11
+ assert defn["name"] == "oauth2-proxy"
12
+ assert defn["category"] == "auth"
13
+ assert defn["default"] is False
14
+ assert defn["profile"] == "proxy"
15
+
16
+
17
+ def test_oauth2_proxy_plugin_metadata():
18
+ """Validate oauth2-proxy plugin metadata tags and name."""
19
+ plugin = Oauth2ProxyServicePlugin()
20
+ meta = plugin.metadata
21
+
22
+ assert meta.name == "oauth2-proxy"
23
+ assert "auth" in meta.tags
24
+ assert "oidc" in meta.tags
25
+
26
+
27
+ def test_oauth2_proxy_not_publicly_routed():
28
+ """Verify oauth2-proxy has no traefik.enable label (internal only)."""
29
+ plugin = Oauth2ProxyServicePlugin()
30
+ defn = plugin.service_definition
31
+ labels = defn.get("compose", {}).get("labels", {})
32
+
33
+ assert labels.get("traefik.enable") != "true"
34
+
35
+
36
+ def test_oauth2_proxy_image_pinned():
37
+ """Verify oauth2-proxy uses a pinned image version."""
38
+ plugin = Oauth2ProxyServicePlugin()
39
+ defn = plugin.service_definition
40
+
41
+ assert "oauth2-proxy" in defn["image"]
42
+ assert ":" in defn["image"], "Image must be version-pinned"