첫 커밋: 로컬 프로젝트 업로드
This commit is contained in:
32
baron-sso/docker/ory/clickhouse/init.sql
Normal file
32
baron-sso/docker/ory/clickhouse/init.sql
Normal file
@@ -0,0 +1,32 @@
|
||||
CREATE DATABASE IF NOT EXISTS ory;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ory.oathkeeper_access_logs (
|
||||
timestamp DateTime64(3) DEFAULT now64(3),
|
||||
request_id String DEFAULT '',
|
||||
method String DEFAULT '',
|
||||
path String DEFAULT '',
|
||||
status UInt16 DEFAULT 0,
|
||||
latency_ms UInt32 DEFAULT 0,
|
||||
client_id String DEFAULT '',
|
||||
rp String DEFAULT '',
|
||||
action String DEFAULT '',
|
||||
target String DEFAULT '',
|
||||
rule_id String DEFAULT '',
|
||||
host String DEFAULT '',
|
||||
scheme String DEFAULT '',
|
||||
query String DEFAULT '',
|
||||
upstream_url String DEFAULT '',
|
||||
subject String DEFAULT '',
|
||||
parent_session_id String DEFAULT '',
|
||||
client_ip String DEFAULT '',
|
||||
user_agent String DEFAULT '',
|
||||
referer String DEFAULT '',
|
||||
decision String DEFAULT '',
|
||||
bytes_in UInt64 DEFAULT 0,
|
||||
bytes_out UInt64 DEFAULT 0,
|
||||
trace_id String DEFAULT '',
|
||||
span_id String DEFAULT '',
|
||||
raw String DEFAULT ''
|
||||
) ENGINE = MergeTree()
|
||||
ORDER BY (timestamp, request_id)
|
||||
TTL timestamp + INTERVAL 30 DAY;
|
||||
98
baron-sso/docker/ory/hydra/hydra.yml.template
Normal file
98
baron-sso/docker/ory/hydra/hydra.yml.template
Normal file
@@ -0,0 +1,98 @@
|
||||
dsn: ${HYDRA_DSN}
|
||||
|
||||
serve:
|
||||
cookies:
|
||||
same_site_mode: Lax
|
||||
admin:
|
||||
cors:
|
||||
enabled: true
|
||||
allowed_origins:
|
||||
- "*"
|
||||
allowed_methods:
|
||||
- POST
|
||||
- GET
|
||||
- PUT
|
||||
- PATCH
|
||||
- DELETE
|
||||
- CONNECT
|
||||
- HEAD
|
||||
- OPTIONS
|
||||
- TRACE
|
||||
allowed_headers:
|
||||
- Authorization
|
||||
- Accept
|
||||
- Content-Type
|
||||
- Content-Length
|
||||
- Accept-Language
|
||||
- Content-Language
|
||||
exposed_headers:
|
||||
- Content-Type
|
||||
- Cache-Control
|
||||
- Expires
|
||||
- Last-Modified
|
||||
- Pragma
|
||||
- Content-Length
|
||||
- Content-Language
|
||||
public:
|
||||
cors:
|
||||
enabled: true
|
||||
allowed_origins:
|
||||
- "*"
|
||||
allowed_methods:
|
||||
- POST
|
||||
- GET
|
||||
- PUT
|
||||
- PATCH
|
||||
- DELETE
|
||||
- CONNECT
|
||||
- HEAD
|
||||
- OPTIONS
|
||||
- TRACE
|
||||
allowed_headers:
|
||||
- Authorization
|
||||
- Accept
|
||||
- Content-Type
|
||||
- Content-Length
|
||||
- Accept-Language
|
||||
- Content-Language
|
||||
exposed_headers:
|
||||
- Content-Type
|
||||
- Cache-Control
|
||||
- Expires
|
||||
- Last-Modified
|
||||
- Pragma
|
||||
- Content-Length
|
||||
- Content-Language
|
||||
allow_credentials: true
|
||||
|
||||
urls:
|
||||
self:
|
||||
issuer: http://127.0.0.1:4444
|
||||
consent: http://127.0.0.1:3000/consent
|
||||
login: http://127.0.0.1:3000/login
|
||||
logout: http://127.0.0.1:3000/logout
|
||||
device:
|
||||
verification: http://127.0.0.1:3000/device/verify
|
||||
success: http://127.0.0.1:3000/device/success
|
||||
|
||||
secrets:
|
||||
system:
|
||||
- ${HYDRA_SYSTEM_SECRET}
|
||||
|
||||
webfinger:
|
||||
oidc_discovery:
|
||||
client_registration_url: http://127.0.0.1:4444/oauth2/register
|
||||
|
||||
oidc:
|
||||
subject_identifiers:
|
||||
supported_types:
|
||||
- pairwise
|
||||
- public
|
||||
pairwise:
|
||||
salt: youReallyNeedToChangeThis
|
||||
dynamic_client_registration:
|
||||
enabled: true
|
||||
|
||||
ttl:
|
||||
access_token: 15m
|
||||
id_token: 15m
|
||||
24
baron-sso/docker/ory/init-db/01_create_dbs.sh
Normal file
24
baron-sso/docker/ory/init-db/01_create_dbs.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# 환경 변수에서 DB 이름 가져오기 (기본값 설정)
|
||||
KRATOS_DB=${KRATOS_DB:-ory_kratos}
|
||||
HYDRA_DB=${HYDRA_DB:-ory_hydra}
|
||||
KETO_DB=${KETO_DB:-ory_keto}
|
||||
|
||||
# 함수 정의: DB가 없으면 생성
|
||||
create_db_if_not_exists() {
|
||||
local dbname=$1
|
||||
if ! psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" -lqt | cut -d \| -f 1 | grep -qw "$dbname"; then
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
|
||||
CREATE DATABASE $dbname;
|
||||
EOSQL
|
||||
echo "Database '$dbname' created."
|
||||
else
|
||||
echo "Database '$dbname' already exists."
|
||||
fi
|
||||
}
|
||||
|
||||
create_db_if_not_exists "$KRATOS_DB"
|
||||
create_db_if_not_exists "$HYDRA_DB"
|
||||
create_db_if_not_exists "$KETO_DB"
|
||||
15
baron-sso/docker/ory/keto/keto.yml.template
Normal file
15
baron-sso/docker/ory/keto/keto.yml.template
Normal file
@@ -0,0 +1,15 @@
|
||||
version: v0.11.0
|
||||
dsn: ${KETO_DSN}
|
||||
serve:
|
||||
read:
|
||||
host: 0.0.0.0
|
||||
port: 4466
|
||||
write:
|
||||
host: 0.0.0.0
|
||||
port: 4467
|
||||
|
||||
namespaces:
|
||||
location: file:///etc/config/keto/namespaces.ts
|
||||
|
||||
log:
|
||||
level: debug
|
||||
150
baron-sso/docker/ory/keto/namespaces.ts
Normal file
150
baron-sso/docker/ory/keto/namespaces.ts
Normal file
@@ -0,0 +1,150 @@
|
||||
import { Namespace, Context, SubjectSet } from "@ory/keto-definitions"
|
||||
|
||||
class User implements Namespace {}
|
||||
|
||||
class System implements Namespace {
|
||||
related: {
|
||||
super_admins: User[]
|
||||
authenticated_users: User[]
|
||||
}
|
||||
|
||||
permits = {
|
||||
manage_all: (ctx: Context): boolean =>
|
||||
this.related.super_admins.includes(ctx.subject)
|
||||
}
|
||||
}
|
||||
|
||||
class Tenant implements Namespace {
|
||||
related: {
|
||||
owners: (User | SubjectSet<System, "super_admins">)[]
|
||||
admins: (User | SubjectSet<System, "super_admins">)[]
|
||||
members: (User | SubjectSet<System, "super_admins"> | SubjectSet<Tenant, "admins"> | SubjectSet<Tenant, "owners">)[]
|
||||
parents: Tenant[]
|
||||
developer_console_viewer: (User | SubjectSet<System, "super_admins">)[]
|
||||
developer_console_grant_manager: (User | SubjectSet<System, "super_admins">)[]
|
||||
}
|
||||
|
||||
permits = {
|
||||
view: (ctx: Context): boolean =>
|
||||
this.related.members.includes(ctx.subject) ||
|
||||
this.related.admins.includes(ctx.subject) ||
|
||||
this.related.owners.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((p) => p.permits.view(ctx)),
|
||||
|
||||
manage: (ctx: Context): boolean =>
|
||||
this.related.admins.includes(ctx.subject) ||
|
||||
this.related.owners.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((p) => p.permits.manage(ctx)),
|
||||
|
||||
manage_admins: (ctx: Context): boolean =>
|
||||
this.related.owners.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((p) => p.permits.manage_admins(ctx)),
|
||||
|
||||
create_subtenant: (ctx: Context): boolean =>
|
||||
this.permits.manage(ctx),
|
||||
|
||||
view_dev_console: (ctx: Context): boolean =>
|
||||
this.related.developer_console_viewer.includes(ctx.subject) ||
|
||||
this.permits.grant_dev_permissions(ctx) ||
|
||||
this.permits.manage(ctx) ||
|
||||
this.related.parents.traverse((p) => p.permits.view_dev_console(ctx)),
|
||||
|
||||
grant_dev_permissions: (ctx: Context): boolean =>
|
||||
this.related.developer_console_grant_manager.includes(ctx.subject) ||
|
||||
this.permits.manage_admins(ctx) ||
|
||||
this.related.parents.traverse((p) => p.permits.grant_dev_permissions(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
class RelyingParty implements Namespace {
|
||||
related: {
|
||||
admins: (User | SubjectSet<System, "super_admins"> | SubjectSet<Tenant, "admins"> | SubjectSet<Tenant, "owners">)[]
|
||||
parents: Tenant[]
|
||||
access: (User | SubjectSet<Tenant, "members"> | SubjectSet<System, "authenticated_users"> | SubjectSet<System, "super_admins">)[]
|
||||
creator: (User | SubjectSet<System, "super_admins">)[]
|
||||
config_editor: (User | SubjectSet<System, "super_admins">)[]
|
||||
secret_viewer: (User | SubjectSet<System, "super_admins">)[]
|
||||
secret_rotator: (User | SubjectSet<System, "super_admins">)[]
|
||||
jwks_viewer: (User | SubjectSet<System, "super_admins">)[]
|
||||
jwks_operator: (User | SubjectSet<System, "super_admins">)[]
|
||||
consent_viewer: (User | SubjectSet<System, "super_admins">)[]
|
||||
consent_revoker: (User | SubjectSet<System, "super_admins">)[]
|
||||
relationship_viewer: (User | SubjectSet<System, "super_admins">)[]
|
||||
audit_viewer: (User | SubjectSet<System, "super_admins">)[]
|
||||
status_operator: (User | SubjectSet<System, "super_admins">)[]
|
||||
}
|
||||
|
||||
permits = {
|
||||
view: (ctx: Context): boolean =>
|
||||
this.related.admins.includes(ctx.subject) ||
|
||||
this.related.config_editor.includes(ctx.subject) ||
|
||||
this.related.secret_viewer.includes(ctx.subject) ||
|
||||
this.related.secret_rotator.includes(ctx.subject) ||
|
||||
this.related.jwks_viewer.includes(ctx.subject) ||
|
||||
this.related.jwks_operator.includes(ctx.subject) ||
|
||||
this.related.consent_viewer.includes(ctx.subject) ||
|
||||
this.related.consent_revoker.includes(ctx.subject) ||
|
||||
this.related.relationship_viewer.includes(ctx.subject) ||
|
||||
this.related.audit_viewer.includes(ctx.subject) ||
|
||||
this.related.status_operator.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((t) => t.permits.view(ctx)) ||
|
||||
this.related.parents.traverse((t) => t.permits.view_dev_console(ctx)),
|
||||
|
||||
manage: (ctx: Context): boolean =>
|
||||
this.related.admins.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((t) => t.permits.manage(ctx)),
|
||||
|
||||
create: (ctx: Context): boolean =>
|
||||
this.related.creator.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((t) => t.permits.grant_dev_permissions(ctx)) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
edit_config: (ctx: Context): boolean =>
|
||||
this.related.config_editor.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
view_secret: (ctx: Context): boolean =>
|
||||
this.related.secret_viewer.includes(ctx.subject) ||
|
||||
this.permits.rotate_secret(ctx) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
rotate_secret: (ctx: Context): boolean =>
|
||||
this.related.secret_rotator.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
view_jwks: (ctx: Context): boolean =>
|
||||
this.related.jwks_viewer.includes(ctx.subject) ||
|
||||
this.permits.operate_jwks(ctx) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
operate_jwks: (ctx: Context): boolean =>
|
||||
this.related.jwks_operator.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
view_consents: (ctx: Context): boolean =>
|
||||
this.related.consent_viewer.includes(ctx.subject) ||
|
||||
this.permits.revoke_consents(ctx) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
revoke_consents: (ctx: Context): boolean =>
|
||||
this.related.consent_revoker.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
view_relationships: (ctx: Context): boolean =>
|
||||
this.related.relationship_viewer.includes(ctx.subject) ||
|
||||
this.related.parents.traverse((t) => t.permits.grant_dev_permissions(ctx)) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
view_audit_logs: (ctx: Context): boolean =>
|
||||
this.related.audit_viewer.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
change_status: (ctx: Context): boolean =>
|
||||
this.related.status_operator.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx),
|
||||
|
||||
access: (ctx: Context): boolean =>
|
||||
this.related.access.includes(ctx.subject) ||
|
||||
this.permits.manage(ctx)
|
||||
}
|
||||
}
|
||||
6
baron-sso/docker/ory/keto/namespaces.yml
Normal file
6
baron-sso/docker/ory/keto/namespaces.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- id: 0
|
||||
name: default
|
||||
- id: 1
|
||||
name: roles
|
||||
- id: 2
|
||||
name: permissions
|
||||
8
baron-sso/docker/ory/kratos/courier-http.jsonnet
Normal file
8
baron-sso/docker/ory/kratos/courier-http.jsonnet
Normal file
@@ -0,0 +1,8 @@
|
||||
// Kratos courier HTTP payload을 backend로 전달하는 템플릿입니다.
|
||||
function(ctx)
|
||||
local data = if std.objectHas(ctx, "template_data") && ctx.template_data != null then ctx.template_data else {};
|
||||
{
|
||||
recipient: ctx.recipient,
|
||||
template_type: ctx.template_type,
|
||||
template_data: data,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<body style="font-family: sans-serif; line-height: 1.6;">
|
||||
<h2>Baron SSO 로그인</h2>
|
||||
<p>아래 버튼을 클릭하면 로그인이 완료됩니다.</p>
|
||||
<!-- 운영 링크: https://app.brsw.kr/verify?loginId={{ .To }}&code={{ .LoginCode }} -->
|
||||
<p>
|
||||
<a href="http://localhost:5000/verify?loginId={{ .To }}&code={{ .LoginCode }}"
|
||||
style="display: inline-block; padding: 10px 16px; background: #1a1f2c; color: #fff; text-decoration: none; border-radius: 6px;">
|
||||
로그인 완료하기
|
||||
</a>
|
||||
</p>
|
||||
<p>또는 아래 로그인 코드를 입력해도 됩니다.</p>
|
||||
<p style="font-size: 18px; font-weight: bold;">{{ .LoginCode }}</p>
|
||||
<p style="color: #666; font-size: 12px;">요청하지 않았다면 이 메일을 무시해 주세요.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
Baron SSO 로그인
|
||||
|
||||
# 운영 링크: https://app.brsw.kr/verify?loginId={{ .To }}&code={{ .LoginCode }}
|
||||
|
||||
아래 링크를 클릭하면 로그인이 완료됩니다.
|
||||
http://localhost:5000/verify?loginId={{ .To }}&code={{ .LoginCode }}
|
||||
|
||||
로그인 코드: {{ .LoginCode }}
|
||||
|
||||
요청하지 않았다면 이 메일을 무시해 주세요.
|
||||
@@ -0,0 +1 @@
|
||||
Baron SSO 로그인 링크
|
||||
@@ -0,0 +1,4 @@
|
||||
[Baron 로그인] 로그인 링크
|
||||
# 운영 링크: https://app.brsw.kr/verify?loginId={{ .To }}&code={{ .LoginCode }}
|
||||
http://localhost:5000/verify?loginId={{ .To }}&code={{ .LoginCode }}
|
||||
코드: {{ .LoginCode }}
|
||||
126
baron-sso/docker/ory/kratos/identity.schema.json
Normal file
126
baron-sso/docker/ory/kratos/identity.schema.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"$id": "https://schemas.ory.sh/presets/kratos/identity.email.schema.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Person",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"traits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"custom_login_ids": {
|
||||
"type": "array",
|
||||
"title": "Custom Login IDs",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"ory.sh/kratos": {
|
||||
"credentials": {
|
||||
"password": {
|
||||
"identifier": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
"title": "E-Mail",
|
||||
"minLength": 3,
|
||||
"ory.sh/kratos": {
|
||||
"credentials": {
|
||||
"password": {
|
||||
"identifier": true
|
||||
},
|
||||
"code": {
|
||||
"identifier": true,
|
||||
"via": "email"
|
||||
}
|
||||
},
|
||||
"recovery": {
|
||||
"via": "email"
|
||||
},
|
||||
"verification": {
|
||||
"via": "email"
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"title": "Name"
|
||||
},
|
||||
"phone_number": {
|
||||
"type": "string",
|
||||
"title": "Phone Number",
|
||||
"minLength": 7,
|
||||
"ory.sh/kratos": {
|
||||
"credentials": {
|
||||
"password": {
|
||||
"identifier": true
|
||||
},
|
||||
"code": {
|
||||
"identifier": true,
|
||||
"via": "sms"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"department": {
|
||||
"type": "string",
|
||||
"title": "Department"
|
||||
},
|
||||
"affiliationType": {
|
||||
"type": "string",
|
||||
"title": "Affiliation Type"
|
||||
},
|
||||
"companyCode": {
|
||||
"type": "string",
|
||||
"title": "Company Code"
|
||||
},
|
||||
"role": {
|
||||
"type": "string",
|
||||
"title": "Role"
|
||||
},
|
||||
"tenant_id": {
|
||||
"type": "string",
|
||||
"title": "Tenant ID"
|
||||
},
|
||||
"displayname": {
|
||||
"type": "string",
|
||||
"title": "Display Name"
|
||||
},
|
||||
"completeForm": {
|
||||
"type": "boolean",
|
||||
"title": "Complete Form"
|
||||
},
|
||||
"team": {
|
||||
"type": "string",
|
||||
"title": "Team"
|
||||
},
|
||||
"taxCode": {
|
||||
"type": "string",
|
||||
"title": "Tax Code"
|
||||
},
|
||||
"familyCompany": {
|
||||
"type": "string",
|
||||
"title": "Family Company"
|
||||
},
|
||||
"familyUniqueKey": {
|
||||
"type": "string",
|
||||
"title": "Family Unique Key"
|
||||
},
|
||||
"personal": {
|
||||
"type": "boolean",
|
||||
"title": "Personal"
|
||||
},
|
||||
"grade": {
|
||||
"type": "string",
|
||||
"title": "Grade"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"email"
|
||||
],
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
98
baron-sso/docker/ory/kratos/kratos.yml.template
Normal file
98
baron-sso/docker/ory/kratos/kratos.yml.template
Normal file
@@ -0,0 +1,98 @@
|
||||
version: v26.2.0
|
||||
|
||||
dsn: ${KRATOS_DSN}
|
||||
|
||||
serve:
|
||||
public:
|
||||
base_url: ${KRATOS_BROWSER_URL:-http://localhost:4433/}
|
||||
cors:
|
||||
enabled: true
|
||||
allowed_origins:
|
||||
- http://localhost:5000
|
||||
- http://localhost:5173
|
||||
- http://localhost:5174
|
||||
- http://localhost:5175
|
||||
- http://backend:3000
|
||||
- http://baron_backend:3000
|
||||
admin:
|
||||
base_url: ${KRATOS_ADMIN_URL:-http://localhost:4434/}
|
||||
|
||||
session:
|
||||
cookie:
|
||||
domain: ${KRATOS_SESSION_COOKIE_DOMAIN}
|
||||
same_site: Lax
|
||||
path: /
|
||||
|
||||
selfservice:
|
||||
default_browser_return_url: ${KRATOS_UI_URL:-http://localhost:5000/}
|
||||
allowed_return_urls:
|
||||
${KRATOS_ALLOWED_RETURN_URLS_YAML}
|
||||
|
||||
methods:
|
||||
password:
|
||||
enabled: true
|
||||
link:
|
||||
enabled: true
|
||||
code:
|
||||
enabled: true
|
||||
passwordless_enabled: true
|
||||
|
||||
flows:
|
||||
error:
|
||||
ui_url: ${KRATOS_UI_URL:-http://localhost:5000}/error
|
||||
settings:
|
||||
ui_url: ${KRATOS_UI_URL:-http://localhost:5000}/error?error=settings_disabled
|
||||
privileged_session_max_age: 15m
|
||||
recovery:
|
||||
ui_url: ${KRATOS_UI_URL:-http://localhost:5000}/recovery
|
||||
use: code
|
||||
verification:
|
||||
ui_url: ${KRATOS_UI_URL:-http://localhost:5000}/verification
|
||||
use: code
|
||||
logout:
|
||||
after:
|
||||
default_browser_return_url: ${KRATOS_UI_URL:-http://localhost:5000}/login
|
||||
login:
|
||||
ui_url: ${KRATOS_UI_URL:-http://localhost:5000}/login
|
||||
lifespan: 10m
|
||||
registration:
|
||||
ui_url: ${KRATOS_UI_URL:-http://localhost:5000}/registration
|
||||
lifespan: 10m
|
||||
|
||||
log:
|
||||
level: debug
|
||||
format: text
|
||||
leak_sensitive_values: true
|
||||
|
||||
secrets:
|
||||
cookie:
|
||||
- PLEASE-CHANGE-ME-I-AM-VERY-INSECURE
|
||||
cipher:
|
||||
- 32-LONG-SECRET-NOT-SECURE-AT-ALL
|
||||
|
||||
ciphers:
|
||||
algorithm: xchacha20-poly1305
|
||||
|
||||
hashers:
|
||||
algorithm: bcrypt
|
||||
bcrypt:
|
||||
cost: 8
|
||||
|
||||
identity:
|
||||
default_schema_id: default
|
||||
schemas:
|
||||
- id: default
|
||||
url: file:///etc/config/kratos/identity.schema.json
|
||||
|
||||
courier:
|
||||
template_override_path: /etc/config/kratos/courier-templates
|
||||
delivery_strategy: http
|
||||
http:
|
||||
request_config:
|
||||
url: http://baron_backend:3000/api/v1/auth/webhooks/kratos-courier
|
||||
method: POST
|
||||
body: file:///etc/config/kratos/courier-http.jsonnet
|
||||
headers:
|
||||
Content-Type: application/json
|
||||
smtp:
|
||||
connection_uri: smtps://test:test@mailslurper:1025/?skip_ssl_verify=true
|
||||
45
baron-sso/docker/ory/oathkeeper/entrypoint.sh
Normal file
45
baron-sso/docker/ory/oathkeeper/entrypoint.sh
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
APP_ENV_VALUE="${APP_ENV:-}"
|
||||
|
||||
case "$APP_ENV_VALUE" in
|
||||
production|prod)
|
||||
RULES_FILE="/etc/config/oathkeeper/rules.prod.json"
|
||||
;;
|
||||
stage|staging)
|
||||
RULES_FILE="/etc/config/oathkeeper/rules.stage.json"
|
||||
;;
|
||||
*)
|
||||
RULES_FILE="/etc/config/oathkeeper/rules.json"
|
||||
;;
|
||||
esac
|
||||
|
||||
export RULES_FILE
|
||||
|
||||
echo "[oathkeeper] APP_ENV=$APP_ENV_VALUE rules=$RULES_FILE"
|
||||
|
||||
RUNTIME_DIR="/tmp/oathkeeper"
|
||||
RULES_ACTIVE="${RUNTIME_DIR}/rules.active.json"
|
||||
if [ ! -f "$RULES_FILE" ]; then
|
||||
echo "[oathkeeper] rules file not found: $RULES_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$RUNTIME_DIR"
|
||||
cp -f "$RULES_FILE" "$RULES_ACTIVE"
|
||||
|
||||
LOG_DIR="/var/log/oathkeeper"
|
||||
LOG_FILE="${LOG_DIR}/access.log"
|
||||
mkdir -p "$LOG_DIR"
|
||||
if ! touch "$LOG_FILE" 2>/dev/null; then
|
||||
echo "[oathkeeper] log file not writable: $LOG_FILE"
|
||||
ls -ld "$LOG_DIR" || true
|
||||
LOG_FILE=""
|
||||
fi
|
||||
|
||||
if [ -n "$LOG_FILE" ]; then
|
||||
exec /bin/sh -c "oathkeeper serve proxy -c /etc/config/oathkeeper/oathkeeper.yml 2>&1 | tee -a \"$LOG_FILE\""
|
||||
fi
|
||||
|
||||
exec /bin/sh -c "oathkeeper serve proxy -c /etc/config/oathkeeper/oathkeeper.yml"
|
||||
69
baron-sso/docker/ory/oathkeeper/oathkeeper.yml.template
Normal file
69
baron-sso/docker/ory/oathkeeper/oathkeeper.yml.template
Normal file
@@ -0,0 +1,69 @@
|
||||
serve:
|
||||
proxy:
|
||||
port: 4455
|
||||
api:
|
||||
port: 4456
|
||||
|
||||
log:
|
||||
level: info
|
||||
format: json
|
||||
|
||||
errors:
|
||||
fallback:
|
||||
- json
|
||||
|
||||
access_rules:
|
||||
repositories:
|
||||
- file:///tmp/oathkeeper/rules.active.json
|
||||
|
||||
authenticators:
|
||||
noop:
|
||||
enabled: true
|
||||
cookie_session:
|
||||
enabled: true
|
||||
config:
|
||||
check_session_url: http://kratos:4433/sessions/whoami
|
||||
preserve_path: true
|
||||
extra_from: "@this"
|
||||
subject_from: "identity.id"
|
||||
oauth2_introspection:
|
||||
enabled: true
|
||||
config:
|
||||
introspection_url: http://hydra:4444/oauth2/introspect
|
||||
pre_authorization:
|
||||
enabled: true
|
||||
client_id: ${OATHKEEPER_INTROSPECT_CLIENT_ID:-oathkeeper-introspect}
|
||||
client_secret: ${OATHKEEPER_INTROSPECT_CLIENT_SECRET:-oathkeeper-secret}
|
||||
token_url: http://hydra:4444/oauth2/token
|
||||
jwt:
|
||||
enabled: true
|
||||
config:
|
||||
jwks_urls:
|
||||
- http://hydra:4444/.well-known/jwks.json
|
||||
trusted_issuers:
|
||||
- http://hydra:4444/
|
||||
scope_strategy: none
|
||||
|
||||
authorizers:
|
||||
allow:
|
||||
enabled: true
|
||||
remote_json:
|
||||
enabled: true
|
||||
config:
|
||||
remote: http://keto:4466/check
|
||||
payload: |
|
||||
{
|
||||
"namespace": "permissions",
|
||||
"object": "{{ print .Request.URL.Path }}",
|
||||
"relation": "access",
|
||||
"subject_id": "{{ print .Subject }}"
|
||||
}
|
||||
|
||||
mutators:
|
||||
noop:
|
||||
enabled: true
|
||||
id_token:
|
||||
enabled: true
|
||||
config:
|
||||
issuer_url: http://127.0.0.1:4456/
|
||||
jwks_url: file:///etc/config/oathkeeper/jwks.json
|
||||
159
baron-sso/docker/ory/oathkeeper/rules.active.json
Normal file
159
baron-sso/docker/ory/oathkeeper/rules.active.json
Normal file
@@ -0,0 +1,159 @@
|
||||
[
|
||||
{
|
||||
"id": "public-health",
|
||||
"description": "공개 헬스체크",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/health",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-preflight",
|
||||
"description": "CORS preflight",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-auth",
|
||||
"description": "인증/회원가입 등 공개 엔드포인트",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/auth/<.*>",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-command",
|
||||
"description": "Command 요청은 Backend로 전달 (Audit 강제)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["POST", "PUT", "PATCH", "DELETE"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-query",
|
||||
"description": "Backend Query (admin/dev 포함)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known",
|
||||
"description": "Hydra OIDC Discovery & JWKS",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known-oidc",
|
||||
"description": "Hydra OIDC Discovery & JWKS (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2",
|
||||
"description": "Hydra OAuth2 Endpoints",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2-oidc",
|
||||
"description": "Hydra OAuth2 Endpoints (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo",
|
||||
"description": "Hydra Userinfo",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo-oidc",
|
||||
"description": "Hydra Userinfo (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
}
|
||||
]
|
||||
91
baron-sso/docker/ory/oathkeeper/rules.draft.json
Normal file
91
baron-sso/docker/ory/oathkeeper/rules.draft.json
Normal file
@@ -0,0 +1,91 @@
|
||||
[
|
||||
{
|
||||
"id": "public-health",
|
||||
"description": "공개 헬스체크 (TODO: 도메인 제한)",
|
||||
"match": {
|
||||
"url": "http://<.*>/health",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-auth",
|
||||
"description": "인증/회원가입 등 공개 엔드포인트",
|
||||
"match": {
|
||||
"url": "http://<.*>/api/v1/auth/<.*>",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-command",
|
||||
"description": "Command 요청은 Backend로 전달 (Audit 강제)",
|
||||
"match": {
|
||||
"url": "http://<.*>/api/v1/<.*>",
|
||||
"methods": ["POST", "PUT", "PATCH", "DELETE"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-query",
|
||||
"description": "Backend Query (admin/dev 포함)",
|
||||
"match": {
|
||||
"url": "http://<.*>/api/v1/<.*>",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-public",
|
||||
"description": "Hydra Public API를 /hydra로 노출",
|
||||
"match": {
|
||||
"url": "http://<.*>/hydra/<.*>",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/hydra"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "rp-host-template",
|
||||
"description": "RP 호스트 기반 템플릿. redirect_uri의 host를 기준으로 매칭합니다.",
|
||||
"match": {
|
||||
"url": "<.*>://rp.example.com/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://rp_upstream:8080"
|
||||
},
|
||||
"authenticators": [
|
||||
{ "handler": "cookie_session" },
|
||||
{ "handler": "oauth2_introspection" },
|
||||
{ "handler": "jwt" }
|
||||
],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
}
|
||||
]
|
||||
159
baron-sso/docker/ory/oathkeeper/rules.json
Normal file
159
baron-sso/docker/ory/oathkeeper/rules.json
Normal file
@@ -0,0 +1,159 @@
|
||||
[
|
||||
{
|
||||
"id": "public-health",
|
||||
"description": "공개 헬스체크",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/health",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-preflight",
|
||||
"description": "CORS preflight",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-auth",
|
||||
"description": "인증/회원가입 등 공개 엔드포인트",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/auth/<.*>",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-command",
|
||||
"description": "Command 요청은 Backend로 전달 (Audit 강제)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["POST", "PUT", "PATCH", "DELETE"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-query",
|
||||
"description": "Backend Query (admin/dev 포함)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known",
|
||||
"description": "Hydra OIDC Discovery & JWKS",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known-oidc",
|
||||
"description": "Hydra OIDC Discovery & JWKS (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2",
|
||||
"description": "Hydra OAuth2 Endpoints",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2-oidc",
|
||||
"description": "Hydra OAuth2 Endpoints (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo",
|
||||
"description": "Hydra Userinfo",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo-oidc",
|
||||
"description": "Hydra Userinfo (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
}
|
||||
]
|
||||
159
baron-sso/docker/ory/oathkeeper/rules.prod.json
Normal file
159
baron-sso/docker/ory/oathkeeper/rules.prod.json
Normal file
@@ -0,0 +1,159 @@
|
||||
[
|
||||
{
|
||||
"id": "public-health",
|
||||
"description": "공개 헬스체크 (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/health",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-preflight",
|
||||
"description": "CORS preflight (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-auth",
|
||||
"description": "인증/회원가입 등 공개 엔드포인트 (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/auth/<.*>",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-command",
|
||||
"description": "Command 요청은 Backend로 전달 (Audit 강제)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["POST", "PUT", "PATCH", "DELETE"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-query",
|
||||
"description": "Backend Query (admin/dev 포함)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known",
|
||||
"description": "Hydra OIDC Discovery & JWKS (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known-oidc",
|
||||
"description": "Hydra OIDC Discovery & JWKS with /oidc prefix (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2",
|
||||
"description": "Hydra OAuth2 Endpoints (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2-oidc",
|
||||
"description": "Hydra OAuth2 Endpoints with /oidc prefix (PROD 도메인)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo",
|
||||
"description": "Hydra Userinfo (PROD)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo-oidc",
|
||||
"description": "Hydra Userinfo with /oidc prefix (PROD 도메인)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
}
|
||||
]
|
||||
159
baron-sso/docker/ory/oathkeeper/rules.stage.json
Normal file
159
baron-sso/docker/ory/oathkeeper/rules.stage.json
Normal file
@@ -0,0 +1,159 @@
|
||||
[
|
||||
{
|
||||
"id": "public-health",
|
||||
"description": "공개 헬스체크",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/health",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-preflight",
|
||||
"description": "CORS preflight",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "public-auth",
|
||||
"description": "인증/회원가입 등 공개 엔드포인트",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/auth/<.*>",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-command",
|
||||
"description": "Command 요청은 Backend로 전달 (Audit 강제)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["POST", "PUT", "PATCH", "DELETE"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "backend-query",
|
||||
"description": "Backend Query (admin/dev 포함)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/api/v1/<.*>",
|
||||
"methods": ["GET"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://baron_backend:3000"
|
||||
},
|
||||
"authenticators": [{ "handler": "cookie_session" }],
|
||||
"authorizer": { "handler": "remote_json" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known",
|
||||
"description": "Hydra OIDC Discovery & JWKS",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-well-known-oidc",
|
||||
"description": "Hydra OIDC Discovery & JWKS (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/.well-known/<.*>",
|
||||
"methods": ["GET", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2",
|
||||
"description": "Hydra OAuth2 Endpoints",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-oauth2-oidc",
|
||||
"description": "Hydra OAuth2 Endpoints (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/oauth2/<.*>",
|
||||
"methods": ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo",
|
||||
"description": "Hydra Userinfo",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
},
|
||||
{
|
||||
"id": "hydra-userinfo-oidc",
|
||||
"description": "Hydra Userinfo (with /oidc prefix)",
|
||||
"match": {
|
||||
"url": "<.*>://<[^/]+>/oidc/userinfo",
|
||||
"methods": ["GET", "POST", "OPTIONS"]
|
||||
},
|
||||
"upstream": {
|
||||
"url": "http://hydra:4444",
|
||||
"strip_path": "/oidc"
|
||||
},
|
||||
"authenticators": [{ "handler": "noop" }],
|
||||
"authorizer": { "handler": "allow" },
|
||||
"mutators": [{ "handler": "noop" }]
|
||||
}
|
||||
]
|
||||
183
baron-sso/docker/ory/vector/vector.toml
Normal file
183
baron-sso/docker/ory/vector/vector.toml
Normal file
@@ -0,0 +1,183 @@
|
||||
[sources.oathkeeper_file]
|
||||
type = "file"
|
||||
include = ["/var/log/oathkeeper/access.log"]
|
||||
read_from = "beginning"
|
||||
|
||||
[transforms.oathkeeper_parse]
|
||||
type = "remap"
|
||||
inputs = ["oathkeeper_file"]
|
||||
source = '''
|
||||
raw = to_string(.message) ?? ""
|
||||
parsed = object!(parse_json(raw) ?? {})
|
||||
request_method = to_string(get(parsed, ["request", "method"]) ?? "") ?? ""
|
||||
if request_method == "" { request_method = to_string(get(parsed, ["http_request", "method"]) ?? "") ?? "" }
|
||||
request_path = to_string(get(parsed, ["request", "path"]) ?? "") ?? ""
|
||||
if request_path == "" { request_path = to_string(get(parsed, ["http_request", "path"]) ?? "") ?? "" }
|
||||
request_url = to_string(get(parsed, ["request", "url"]) ?? "") ?? ""
|
||||
if request_url == "" { request_url = to_string(get(parsed, ["http_url"]) ?? "") ?? "" }
|
||||
request_host = to_string(get(parsed, ["request", "host"]) ?? "") ?? ""
|
||||
if request_host == "" { request_host = to_string(get(parsed, ["http_request", "host"]) ?? "") ?? "" }
|
||||
request_scheme = to_string(get(parsed, ["request", "scheme"]) ?? "") ?? ""
|
||||
if request_scheme == "" { request_scheme = to_string(get(parsed, ["http_request", "scheme"]) ?? "") ?? "" }
|
||||
request_query = to_string(get(parsed, ["request", "query"]) ?? "") ?? ""
|
||||
if request_query == "" { request_query = to_string(get(parsed, ["http_request", "query"]) ?? "") ?? "" }
|
||||
response_status = to_int(get(parsed, ["response", "status"]) ?? 0) ?? 0
|
||||
if response_status == 0 { response_status = to_int(get(parsed, ["http_response", "status"]) ?? 0) ?? 0 }
|
||||
response_size = to_int(get(parsed, ["response", "size"]) ?? 0) ?? 0
|
||||
if response_size == 0 { response_size = to_int(get(parsed, ["http_response", "size"]) ?? 0) ?? 0 }
|
||||
response_took = to_int(get(parsed, ["response", "took"]) ?? 0) ?? 0
|
||||
if response_took == 0 { response_took = to_int(get(parsed, ["http_response", "took"]) ?? 0) ?? 0 }
|
||||
identity_id = to_string(get(parsed, ["identity", "id"]) ?? "") ?? ""
|
||||
if identity_id == "" { identity_id = to_string(get(parsed, ["subject"]) ?? "") ?? "" }
|
||||
headers = object(get(parsed, ["headers"]) ?? {}) ?? {}
|
||||
if length(headers) == 0 { headers = object(get(parsed, ["http_request", "headers"]) ?? {}) ?? {} }
|
||||
user_agent = to_string(get(headers, ["User-Agent"]) ?? "") ?? ""
|
||||
if user_agent == "" { user_agent = to_string(get(headers, ["user-agent"]) ?? "") ?? "" }
|
||||
referer = to_string(get(headers, ["Referer"]) ?? "") ?? ""
|
||||
if referer == "" { referer = to_string(get(headers, ["referer"]) ?? "") ?? "" }
|
||||
rule_id = to_string(get(parsed, ["rule", "id"]) ?? "") ?? ""
|
||||
if rule_id == "" { rule_id = to_string(get(parsed, ["rule_id"]) ?? "") ?? "" }
|
||||
upstream_url = to_string(get(parsed, ["upstream", "url"]) ?? "") ?? ""
|
||||
if upstream_url == "" { upstream_url = to_string(get(parsed, ["http_url"]) ?? "") ?? "" }
|
||||
client_id = to_string(get(parsed, ["client", "id"]) ?? "") ?? ""
|
||||
parent_session_id = to_string(get(parsed, ["extra", "parent_session_id"]) ?? "") ?? ""
|
||||
parsed_url = parse_url(request_url) ?? {}
|
||||
query_params = get(parsed_url, ["query"]) ?? {}
|
||||
url_path = to_string(get(parsed_url, ["path"]) ?? "") ?? ""
|
||||
parsed_request_query = parse_url("http://localhost/?" + request_query) ?? {}
|
||||
request_query_params = get(parsed_request_query, ["query"]) ?? {}
|
||||
event_path = to_string(parsed.path) ?? to_string(parsed.http_path) ?? ""
|
||||
if event_path == "" { event_path = request_path }
|
||||
if event_path == "" { event_path = url_path }
|
||||
if event_path == "" { event_path = request_url }
|
||||
event_client_id = to_string(parsed.client_id) ?? ""
|
||||
if event_client_id == "" { event_client_id = client_id }
|
||||
if event_client_id == "" { event_client_id = to_string(get(query_params, ["client_id"]) ?? "") ?? "" }
|
||||
if event_client_id == "" { event_client_id = to_string(get(query_params, ["clientId"]) ?? "") ?? "" }
|
||||
if event_client_id == "" { event_client_id = to_string(get(request_query_params, ["client_id"]) ?? "") ?? "" }
|
||||
if event_client_id == "" { event_client_id = to_string(get(request_query_params, ["clientId"]) ?? "") ?? "" }
|
||||
event_latency_ms = to_int(parsed.latency_ms) ?? to_int(parsed.duration_ms) ?? 0
|
||||
if event_latency_ms == 0 && response_took != 0 {
|
||||
event_latency_ms = to_int(to_float(response_took) / 1000000.0)
|
||||
}
|
||||
event_client_ip = to_string(parsed.client_ip) ?? to_string(parsed.remote_ip) ?? to_string(parsed.ip) ?? ""
|
||||
if event_client_ip == "" { event_client_ip = to_string(get(headers, ["X-Real-Ip"]) ?? "") ?? "" }
|
||||
if event_client_ip == "" { event_client_ip = to_string(get(headers, ["x-real-ip"]) ?? "") ?? "" }
|
||||
if event_client_ip == "" { event_client_ip = to_string(get(headers, ["X-Forwarded-For"]) ?? "") ?? "" }
|
||||
if event_client_ip == "" { event_client_ip = to_string(get(headers, ["x-forwarded-for"]) ?? "") ?? "" }
|
||||
event_decision = to_string(parsed.decision) ?? to_string(parsed.result) ?? ""
|
||||
if event_decision == "" && exists(parsed.granted) {
|
||||
if parsed.granted == true {
|
||||
event_decision = "granted"
|
||||
} else {
|
||||
event_decision = "denied"
|
||||
}
|
||||
}
|
||||
event_status = to_int(get(parsed, ["status"]) ?? 0) ?? 0
|
||||
if event_status == 0 { event_status = to_int(get(parsed, ["status_code"]) ?? 0) ?? 0 }
|
||||
if event_status == 0 { event_status = response_status }
|
||||
event_bytes_out = to_int(get(parsed, ["bytes_out"]) ?? 0) ?? 0
|
||||
if event_bytes_out == 0 { event_bytes_out = to_int(get(parsed, ["response_bytes"]) ?? 0) ?? 0 }
|
||||
if event_bytes_out == 0 { event_bytes_out = response_size }
|
||||
event_method = to_string(get(parsed, ["method"]) ?? "") ?? ""
|
||||
if event_method == "" { event_method = to_string(get(parsed, ["http_method"]) ?? "") ?? "" }
|
||||
if event_method == "" { event_method = request_method }
|
||||
event_host = to_string(get(parsed, ["host"]) ?? "") ?? ""
|
||||
if event_host == "" { event_host = to_string(get(parsed, ["http_host"]) ?? "") ?? "" }
|
||||
if event_host == "" { event_host = request_host }
|
||||
event_scheme = to_string(get(parsed, ["scheme"]) ?? "") ?? ""
|
||||
if event_scheme == "" { event_scheme = request_scheme }
|
||||
event_query = to_string(get(parsed, ["query"]) ?? "") ?? ""
|
||||
if event_query == "" { event_query = request_query }
|
||||
event_user_agent = to_string(get(parsed, ["user_agent"]) ?? "") ?? ""
|
||||
if event_user_agent == "" { event_user_agent = to_string(get(parsed, ["http_user_agent"]) ?? "") ?? "" }
|
||||
if event_user_agent == "" { event_user_agent = user_agent }
|
||||
|
||||
. = {
|
||||
"request_id": to_string(parsed.request_id) ?? to_string(parsed.req_id) ?? "",
|
||||
"method": event_method,
|
||||
"path": event_path,
|
||||
"status": event_status,
|
||||
"latency_ms": event_latency_ms,
|
||||
"client_id": event_client_id,
|
||||
"rp": to_string(parsed.rp) ?? "",
|
||||
"action": to_string(parsed.action) ?? "",
|
||||
"target": to_string(parsed.target) ?? "",
|
||||
"rule_id": to_string(parsed.rule_id) ?? rule_id,
|
||||
"host": event_host,
|
||||
"scheme": event_scheme,
|
||||
"query": event_query,
|
||||
"upstream_url": to_string(parsed.upstream_url) ?? upstream_url,
|
||||
"subject": to_string(parsed.subject) ?? identity_id,
|
||||
"parent_session_id": to_string(parsed.parent_session_id) ?? parent_session_id,
|
||||
"client_ip": event_client_ip,
|
||||
"user_agent": event_user_agent,
|
||||
"referer": referer,
|
||||
"decision": event_decision,
|
||||
"bytes_in": to_int(parsed.bytes_in) ?? to_int(parsed.request_bytes) ?? 0,
|
||||
"bytes_out": event_bytes_out,
|
||||
"trace_id": to_string(parsed.trace_id) ?? "",
|
||||
"span_id": to_string(parsed.span_id) ?? "",
|
||||
"raw": raw
|
||||
}
|
||||
'''
|
||||
|
||||
[sinks.clickhouse]
|
||||
type = "clickhouse"
|
||||
inputs = ["oathkeeper_parse"]
|
||||
endpoint = "http://ory_clickhouse:8123"
|
||||
database = "ory"
|
||||
table = "oathkeeper_access_logs"
|
||||
compression = "gzip"
|
||||
auth.strategy = "basic"
|
||||
auth.user = "${ORY_CLICKHOUSE_USER}"
|
||||
auth.password = "${ORY_CLICKHOUSE_PASSWORD}"
|
||||
|
||||
[[tests]]
|
||||
name = "parses_oathkeeper_v26_completed_request"
|
||||
|
||||
[[tests.inputs]]
|
||||
insert_at = "oathkeeper_parse"
|
||||
type = "log"
|
||||
|
||||
[tests.inputs.log_fields]
|
||||
message = '{"http_request":{"headers":{"user-agent":"Mozilla/5.0","referer":"http://localhost:5173/","x-real-ip":"172.19.0.1"},"host":"localhost","method":"GET","path":"/oauth2/auth","query":"client_id=orgfront&response_type=code","remote":"172.23.0.2:56744","scheme":"http"},"http_response":{"status":302,"size":1339,"took":4854092},"http_url":"http://hydra:4444/oauth2/auth?client_id=orgfront&redirect_uri=http%3A%2F%2Flocalhost%3A5175%2Fauth%2Fcallback","level":"info","msg":"completed handling request","subject":"","time":"2026-05-06T01:40:51.46074548Z"}'
|
||||
|
||||
[[tests.outputs]]
|
||||
extract_from = "oathkeeper_parse"
|
||||
|
||||
[[tests.outputs.conditions]]
|
||||
type = "vrl"
|
||||
source = '''
|
||||
assert_eq!(.method, "GET")
|
||||
assert_eq!(.path, "/oauth2/auth")
|
||||
assert_eq!(.status, 302)
|
||||
assert_eq!(.client_id, "orgfront")
|
||||
assert_eq!(.host, "localhost")
|
||||
assert_eq!(.scheme, "http")
|
||||
assert_eq!(.user_agent, "Mozilla/5.0")
|
||||
assert_eq!(.referer, "http://localhost:5173/")
|
||||
'''
|
||||
|
||||
[[tests]]
|
||||
name = "parses_oathkeeper_v26_granted_request"
|
||||
|
||||
[[tests.inputs]]
|
||||
insert_at = "oathkeeper_parse"
|
||||
type = "log"
|
||||
|
||||
[tests.inputs.log_fields]
|
||||
message = '{"audience":"application","granted":true,"http_host":"hydra:4444","http_method":"GET","http_url":"http://hydra:4444/oauth2/auth?client_id=orgfront&redirect_uri=http%3A%2F%2Flocalhost%3A5175%2Fauth%2Fcallback&response_type=code","http_user_agent":"curl/8.10.1","level":"info","msg":"Access request granted","service_name":"ORY Oathkeeper","service_version":"v26.2.0","subject":"","time":"2026-05-06T01:52:25.431Z"}'
|
||||
|
||||
[[tests.outputs]]
|
||||
extract_from = "oathkeeper_parse"
|
||||
|
||||
[[tests.outputs.conditions]]
|
||||
type = "vrl"
|
||||
source = '''
|
||||
assert_eq!(.method, "GET")
|
||||
assert_eq!(.path, "/oauth2/auth")
|
||||
assert_eq!(.status, 0)
|
||||
assert_eq!(.client_id, "orgfront")
|
||||
assert_eq!(.decision, "granted")
|
||||
'''
|
||||
Reference in New Issue
Block a user