Skip to content

Commit b124e7f

Browse files
committed
feat: readme and example
1 parent fea9842 commit b124e7f

File tree

7 files changed

+309
-14
lines changed

7 files changed

+309
-14
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/.idea
2+
/target

README.md

Lines changed: 182 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,202 @@ Auth-Bridge is an open-source project that provides proxy capabilities for Kuber
99
- Policy-based automatic credential injection
1010
- Flexible proxy configuration based on [Open Policy Agent](https://www.openpolicyagent.org).
1111

12+
## Prepare
13+
Before installing Auth-Bridge, ensure you have the following prerequisites:
14+
15+
### A Kubernetes cluster
16+
You can use [kind](https://kind.sigs.k8s.io) for local development.
17+
Alternatively [OrbStack](https://orbstack.dev) provides a lightweight Kubernetes environment.
18+
19+
20+
### Install cert-manager
21+
```shell
22+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
23+
```
24+
25+
### Install skaffold
26+
```bash
27+
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 && \
28+
sudo install skaffold /usr/local/bin/
29+
```
30+
1231
## Installation
1332

1433
```bash
15-
# Installation instructions to be added
34+
skaffold deploy
1635
```
1736

1837
## Configuration
1938

20-
Auth-Bridge is configured using a YAML file. Here's a basic configuration example:
39+
Auth-Bridge is configured by ProxyPolicy CRD. Here's a basic configuration example:
2140

2241
```yaml
23-
# Configuration example to be added
42+
apiVersion: auth-bridge.dev/v1alpha1
43+
kind: ProxyPolicy
44+
metadata:
45+
name: basic-auth
46+
namespace: default
47+
spec:
48+
auth:
49+
method: basicAuth
50+
secret:
51+
reference:
52+
name: basic-auth
53+
namespace: <secret namespace>
54+
rules:
55+
- name: basic-rule
56+
validate: |
57+
package proxy
58+
59+
default allow = true
60+
---
61+
apiVersion: v1
62+
kind: Secret
63+
metadata:
64+
name: basic-auth
65+
namespace: default
66+
type: Opaque
67+
stringData:
68+
username: username
69+
password: password
2470
```
2571
72+
## Configuration
73+
74+
Auth-Bridge is configured by ProxyPolicy and Secret. Ensure that your ProxyPolicy and associated Secret are correctly configured based on your chosen authentication method and validation rules.
75+
76+
Here's a basic configuration example:
77+
78+
```yaml
79+
apiVersion: auth-bridge.dev/v1alpha1
80+
kind: ProxyPolicy
81+
metadata:
82+
name: basic-auth
83+
namespace: default
84+
spec:
85+
auth:
86+
method: basicAuth
87+
secret:
88+
reference:
89+
name: basic-auth
90+
namespace: <secret namespace>
91+
rules:
92+
- name: basic-rule
93+
validate: |
94+
package proxy
95+
96+
default allow = true
97+
---
98+
apiVersion: v1
99+
kind: Secret
100+
metadata:
101+
name: basic-auth
102+
namespace: default
103+
type: Opaque
104+
stringData:
105+
username: username
106+
password: password
107+
```
108+
109+
### Field Definition
110+
111+
* `auth.method`
112+
This field specifies the authentication method to be used. It can be set to either:
113+
- `basicAuth`: For basic authentication using a username and password.
114+
- `bearerToken`: For authentication using a bearer token.
115+
116+
* `auth.secret.reference`
117+
This field refers to the Kubernetes Secret containing the authentication credentials.
118+
- For `basicAuth`, the referenced Secret data must contain `username` and `password`
119+
- For `bearerToken`, the referenced Secret data must contain `token`
120+
121+
* `rules.validate`:
122+
This field contains the Open Policy Agent (OPA) validation rule. The OPA script must include a boolean variable
123+
named `allow`, which determines whether the secret should be injected during proxying based on this rule. For example:
124+
125+
```
126+
package proxy
127+
128+
default allow = false
129+
130+
allow {
131+
input.uri == "example.com"
132+
}
133+
```
134+
135+
### Advanced
136+
The OPA script also has access to an input object that contains information about the target request and the pod.
137+
You can use input.<field> in your OPA script to make decisions. The available fields include:
138+
139+
- input.uri: The URI of the target request
140+
- input.query: The query parameters of the target request
141+
- input.body: The body of the target request
142+
- input.meta: Metadata of the pod making the request
143+
144+
In this example, the secret will only be injected if the request host is "example.com".
145+
146+
```
147+
package proxy
148+
149+
default allow = false
150+
151+
allow {
152+
contains(input.uri, "example.com")
153+
input.meta.namespace == "allowed-namespace"
154+
input.query.action == "read"
155+
}
156+
```
157+
26158
## Usage
159+
Using Auth-Bridge involves several key steps:
27160

28-
1. Deploy Auth-Bridge in your Kubernetes cluster
29-
2. Configure your proxy policies and credentials
30-
3. Set the appropriate environment variables or annotations in the Pods that require proxy access
161+
### Configure ProxyPolicy
162+
Create a ProxyPolicy resource to define your proxy rules:
163+
```yaml
164+
apiVersion: auth-bridge.dev/v1alpha1
165+
kind: ProxyPolicy
166+
metadata:
167+
name: proxy-policy
168+
spec:
169+
auth:
170+
method: basicAuth
171+
secret:
172+
reference:
173+
name: <secret name>
174+
namespace: <secret namespace>
175+
rules:
176+
- name: <rule name>
177+
validate: <rule opa>
178+
```
179+
180+
### Create Secret
181+
182+
Create a Secret with correct credentials based on your policy auth method:
183+
184+
```yaml
185+
apiVersion: v1
186+
kind: Secret
187+
metadata:
188+
name: credentials
189+
namespace: default
190+
type: Opaque
191+
stringData:
192+
username: <username>
193+
password: <password>
194+
```
195+
196+
### Set proxy
197+
To enable the Auth-Bridge proxy, set the following environment variables for your application:
198+
```shell
199+
HTTP_PROXY=http://auth-bridge-proxy.auth-bridge:80
200+
HTTPS_PROXY=http://auth-bridge-proxy.auth-bridge:80
201+
http_proxy=http://auth-bridge-proxy.auth-bridge:80
202+
https_proxy=http://auth-bridge-proxy.auth-bridge:80
203+
```
204+
the proxy host `auth-bridge-proxy.auth-bridge` here follows the Kubernetes service naming convention:`<service-name>.<namespace>`
31205

32-
For detailed usage instructions, please refer to our [documentation](#) (link to be added).
206+
For a more detailed demonstration of how these steps come together, please refer to the [examples](tree/@/examples
207+
).
33208

34209
## Contributing
35210

config/deploy/daemonset.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ spec:
1515
control-plane: auth-bridge
1616
spec:
1717
containers:
18-
- image: auth-bridge:v1
18+
- image: auth-bridge:latest
1919
name: proxy
2020
command:
2121
- auth-bridge

examples/basic-auth/nginx.yaml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
apiVersion: v1
3+
kind: ConfigMap
4+
metadata:
5+
name: nginx-config
6+
namespace: auth-bridge-example
7+
data:
8+
nginx.conf: |
9+
events {
10+
worker_connections 1024;
11+
}
12+
http {
13+
server {
14+
listen 80;
15+
server_name localhost;
16+
17+
location /auth {
18+
auth_basic "Restricted Area";
19+
auth_basic_user_file /etc/nginx/.htpasswd;
20+
root /usr/share/nginx/html;
21+
try_files /auth.html =404;
22+
}
23+
24+
location /no-auth {
25+
auth_basic off;
26+
root /usr/share/nginx/html;
27+
try_files /no-auth.html =404;
28+
}
29+
}
30+
}
31+
no-auth.html: |
32+
Hello from no-auth path
33+
auth.html: |
34+
Hello from auth path
35+
.htpasswd: |
36+
auth-user:$1$FDNvyIWe$pMX38FS311281uVenqcyi0
37+
---
38+
apiVersion: v1
39+
kind: Pod
40+
metadata:
41+
labels:
42+
app: nginx
43+
name: nginx
44+
namespace: auth-bridge-example
45+
spec:
46+
containers:
47+
- name: nginx
48+
image: nginx:alpine
49+
ports:
50+
- containerPort: 80
51+
volumeMounts:
52+
- name: nginx-config
53+
mountPath: /etc/nginx/nginx.conf
54+
subPath: nginx.conf
55+
- name: nginx-config
56+
mountPath: /etc/nginx/.htpasswd
57+
subPath: .htpasswd
58+
- name: nginx-config
59+
mountPath: /usr/share/nginx/html/auth.html
60+
subPath: auth.html
61+
- name: nginx-config
62+
mountPath: /usr/share/nginx/html/no-auth.html
63+
subPath: no-auth.html
64+
volumes:
65+
- name: nginx-config
66+
configMap:
67+
name: nginx-config
68+
---
69+
apiVersion: v1
70+
kind: Service
71+
metadata:
72+
name: nginx-service
73+
namespace: auth-bridge-example
74+
spec:
75+
selector:
76+
app: nginx

examples/basic-auth/policy.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
apiVersion: auth-bridge.dev/v1alpha1
2+
kind: ProxyPolicy
3+
metadata:
4+
name: basic-auth
5+
spec:
6+
auth:
7+
method: basicAuth
8+
secret:
9+
reference:
10+
name: basic-auth
11+
namespace: auth-bridge-example
12+
rules:
13+
- name: host-match
14+
validate: |
15+
package proxy
16+
17+
default host = "nginx-service.auth-bridge-example"
18+
default allowed = false
19+
20+
allowed {
21+
contains(input.uri, host)
22+
}
23+
24+
message := "policy does not contain host" {
25+
contains(input.uri, host)
26+
}
27+
---
28+
apiVersion: v1
29+
kind: Secret
30+
metadata:
31+
name: basic-auth
32+
namespace: auth-bridge-example
33+
stringData:
34+
username: auth-user
35+
password: auth-password

skaffold.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ build:
1010
artifacts:
1111
- image: auth-bridge
1212
docker:
13-
dockerfile: Dockerfile
13+
dockerfile: Dockerfile

src/handlers/multi.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,21 @@ impl MultiHandler {
1717
}
1818

1919
impl HttpHandler for MultiHandler {
20-
async fn handle_request(&mut self, ctx: &HttpContext, mut req: Request<Body>) -> RequestOrResponse {
20+
async fn handle_request(&mut self, ctx: &HttpContext, req: Request<Body>) -> RequestOrResponse {
21+
let mut result = RequestOrResponse::Request(req);
22+
2123
for handler in &self.handlers {
22-
match handler.handle_request(ctx, req).await {
23-
RequestOrResponse::Request(new_req) => req = new_req,
24-
response => return response,
24+
match result {
25+
RequestOrResponse::Request(req) => {
26+
result = handler.handle_request(ctx, req).await;
27+
},
28+
RequestOrResponse::Response(_) => {
29+
break;
30+
}
2531
}
2632
}
27-
RequestOrResponse::Request(req)
33+
34+
result
2835
}
2936
}
3037
#[derive(Clone)]

0 commit comments

Comments
 (0)