chore: 문서를 작성할 때 한국어의 표현 작성 스킬 추가 및 1인칭 관점의 글 작성 검증 테스트 추가
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
{
|
||||
"sources": [
|
||||
{
|
||||
"id": "L4121b8d86b",
|
||||
"title": "four pattern tradeoff matrix — Four Keycloak integration patterns",
|
||||
"url": "repo:///docs/four-pattern-tradeoff-matrix.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Four Keycloak integration patterns\n\n| 축 | AP1 SPA direct | AP2 token mediator | AP3 BFF | AP4 edge auth |\n|---|---|---|---|---|\n| OAuth client | public | confidential | confidential | confidential proxy |\n| browser 보유물 | access/refresh token | 짧은 handoff code 또는 app token | HttpOnly session cookie | proxy session cookie |\n| OAuth code 교환 | browser + PKCE | mediator backend | BFF | oauth2-proxy |\n| API bearer 검증 | Spring resource server | mediator/downstream API | BFF 내부 또는 downstream | edge가 인증 후 trusted header |\n| server session | 없음 | handoff 상태만 짧게 | 필수 | proxy cookie/session |\n| XSS token 탈취면 | 가장 큼 | 축소 | browser token 제거 | browser token 제거 |\n| CSRF 주의 | token endpoint/refresh 설계 | app cookie 사용 시 | 필수 방어 | proxy cookie 사용 시 |\n| 수평 확장 상태 | 단순 | handoff store 공유 가능 | session store 필요 | proxy 설정에 따름 |\n| 주 학습 포인트 | PKCE/JWT/RS | token 경계·one-time handoff | oauth2Login/session/CSRF | auth_request/header trust |"
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/four-pattern-tradeoff-matrix.md",
|
||||
"heading": "Four Keycloak integration patterns",
|
||||
"line_start": 1,
|
||||
"line_end": 14,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 45.74042
|
||||
},
|
||||
{
|
||||
"id": "La5d0a70f24",
|
||||
"title": "four pattern tradeoff matrix — 이 repository의 실행 증거",
|
||||
"url": "repo:///docs/four-pattern-tradeoff-matrix.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"## 이 repository의 실행 증거\n\n- AP1: PKCE SPA, issuer/audience, token storage, refresh/logout 검증\n- AP2: confidential client와 one-time access handoff 검증\n- AP3: `oauth2Login` session과 CSRF/SameSite 검증\n- AP4: oauth2-proxy, nginx `auth_request`, spoofed header 제거 검증\n- 공통: local mock Google brokering, First Broker Login, claim/role mapping 검증\n\n각 근거 브랜치와 병합 여부는 `keycloak-branch-manifest.tsv` 및\n`audit-keycloak-branches.sh`로 추적한다."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/four-pattern-tradeoff-matrix.md",
|
||||
"heading": "이 repository의 실행 증거",
|
||||
"line_start": 28,
|
||||
"line_end": 37,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 21.712857
|
||||
},
|
||||
{
|
||||
"id": "L2c120c8093",
|
||||
"title": "four pattern tradeoff matrix — 선택 기준",
|
||||
"url": "repo:///docs/four-pattern-tradeoff-matrix.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"## 선택 기준\n\n- 브라우저에서 OAuth와 token 수명주기를 직접 학습하려면 AP1.\n- 브라우저에 upstream token을 주지 않되 API 호출은 bearer 중심으로 유지하려면\n AP2.\n- token을 browser에서 완전히 제거하고 애플리케이션 단위 인가·세션을\n 중앙화하려면 AP3.\n- 기존 upstream을 수정하기 어렵고 경계에서 일괄 인증하려면 AP4.\n\nGoogle federation은 다섯 번째 인증 패턴이 아니다. 네 패턴 모두 최종적으로\nKeycloak token/session을 소비하며, Google은 Keycloak 앞의 upstream IdP\nhop으로 추가된다."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/four-pattern-tradeoff-matrix.md",
|
||||
"heading": "선택 기준",
|
||||
"line_start": 15,
|
||||
"line_end": 27,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 17.280962
|
||||
},
|
||||
{
|
||||
"id": "L4ec23ba045",
|
||||
"title": "keycloak branch index — Keycloak branch implementation index",
|
||||
"url": "repo:///docs/keycloak-branch-index.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Keycloak branch implementation index\n\nThe source inventory contains 39 `feature-keycloak-*.md` branch notes. This\nrepository preserves one local Git feature branch for every note and merges it\nwith `--no-ff` into either the common `develop` baseline or one of the four\nauthentication-pattern branches.\n\n| Target | Meaning |\n|---|---|\n| `common` | Shared realm, federation, deployment, or governance contract. Merge into `develop`, then propagate to AP1–AP4. |\n| `ap1` | Browser-based OAuth client: vanilla SPA, Authorization Code + PKCE, Resource Server. |\n| `ap2` | Token-mediating confidential backend: browser receives access token only. |\n| `ap3` | BFF: backend owns every OAuth token and browser owns only a session cookie. |\n| `ap4` | Edge forward-auth: oauth2-proxy/Nginx owns login and backend trusts an isolated identity header. |\n\nThe machine-readable registry is\n[`keycloak-branch-manifest.tsv`](keycloak-branch-manifest.tsv). Run:\n\n```bash\n./scripts/audit-keycloak-branches.sh\n```\n\nThe audit succeeds only when all 39 note names have matching local feature\nbranches and each feature tip is reachable from its declared target branch.\n\nGoogle credentials are never committed. The default local acceptance harness\nuses a second Keycloak realm as a controllable OIDC provider so claim mapping\nand unsafe-linking failure paths can be reproduced. A real Google login remains\nan explicit credentialed/public-HTTPS verification profile."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/keycloak-branch-index.md",
|
||||
"heading": "Keycloak branch implementation index",
|
||||
"line_start": 1,
|
||||
"line_end": 29,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 14.830096
|
||||
},
|
||||
{
|
||||
"id": "Lb39734ea9b",
|
||||
"title": "google idp brokering — Google IdP brokering",
|
||||
"url": "repo:///docs/google-idp-brokering.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Google IdP brokering\n\nKeycloak is the only issuer trusted by AP1–AP4. Google is an upstream Identity\nProvider; applications do not receive or validate a Google token."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/google-idp-brokering.md",
|
||||
"heading": "Google IdP brokering",
|
||||
"line_start": 1,
|
||||
"line_end": 5,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 5.851474
|
||||
},
|
||||
{
|
||||
"id": "La28755902d",
|
||||
"title": "google claim to role — Google claim-to-role mapping",
|
||||
"url": "repo:///docs/google-claim-to-role.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Google claim-to-role mapping\n\n`hd=example.test`인 upstream OIDC identity에는 Keycloak realm role\n`employee-role`을 부여한다. 매핑 키는 email이 아니라 Google subject이며,\nrole 조건에 쓰는 `hd` claim은 mock provider와 실제 Google provider에서 같은\n계약을 사용한다.\n\nRealm import는 `oidc-role-idp-mapper`를 선언한다. 실제 Google 설정 스크립트도\n같은 mapper를 upsert한다. 따라서 재실행해도 mapper가 중복되지 않는다.\n\n검증:\n\n```sh\n./scripts/verify-google-claim-to-role.sh\n```\n\n검증기는 mock Google 로그인, Authorization Code + PKCE 교환, 최종 Keycloak\naccess token의 `realm_access.roles`를 차례로 확인한다."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/google-claim-to-role.md",
|
||||
"heading": "Google claim-to-role mapping",
|
||||
"line_start": 1,
|
||||
"line_end": 18,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 4.750257
|
||||
},
|
||||
{
|
||||
"id": "Le8474e5ddd",
|
||||
"title": "https termination — HTTPS termination: nginx or Caddy",
|
||||
"url": "repo:///docs/https-termination.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# HTTPS termination: nginx or Caddy\n\n두 예제 모두 public `443`에서 TLS를 종료하고 private Docker network의\n`keycloak:8080`으로 전달한다. Keycloak 쪽 설정은\n`deploy/reverse-proxy/keycloak.env.example`의 hostname/proxy contract를\n같이 사용한다.\n\n- nginx: 인증서 배포·갱신을 운영자가 담당할 때 적합하다.\n- Caddy: ACME를 통한 인증서 수명주기를 proxy가 담당하게 할 때 간단하다.\n- 둘을 동시에 production entry point로 띄우지 않는다.\n- 인증서와 private key는 repository 또는 image에 포함하지 않는다.\n- HTTP challenge/redirect 및 방화벽의 80/443 허용은 배포 환경에서 별도로\n 결정한다.\n\n검증 스크립트는 임시 자체 서명 인증서를 만들고 두 vendor image에서 설정을\n각각 validate한 뒤 임시 파일을 제거한다.\n\n```sh\n./scripts/verify-https-termination-config.sh\n```"
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/https-termination.md",
|
||||
"heading": "HTTPS termination: nginx or Caddy",
|
||||
"line_start": 1,
|
||||
"line_end": 20,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 2.684955
|
||||
},
|
||||
{
|
||||
"id": "L0eb117abf5",
|
||||
"title": "google redirect uri policy — Google redirect URI policy",
|
||||
"url": "repo:///docs/google-redirect-uri-policy.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Google redirect URI policy\n\nGoogle에 등록하는 redirect URI는 애플리케이션 SPA callback이 아니라 Keycloak\nbroker endpoint다.\n\n```text\nhttps://auth.example.test/realms/keycloak-patterns/broker/google/endpoint\n```\n\n규칙:\n\n- production URI는 HTTPS와 고정된 public Keycloak origin을 사용한다.\n- wildcard, path prefix, 임시 tunnel hostname을 production OAuth client에\n 등록하지 않는다.\n- 개발·스테이징·운영은 Google OAuth client를 분리한다.\n- reverse proxy가 있더라도 Google이 보는 URI와 Keycloak이 생성하는 URI가\n byte-for-byte 같아야 한다.\n- `configure-google-idp.sh`가 출력하는 URI를 Google Console의 Authorized\n redirect URI와 대조한다.\n\n```sh\nPUBLIC_KEYCLOAK_URL=https://auth.example.test \\\n ./scripts/verify-google-redirect-uri-policy.sh\n```"
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/google-redirect-uri-policy.md",
|
||||
"heading": "Google redirect URI policy",
|
||||
"line_start": 1,
|
||||
"line_end": 24,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 2.514945
|
||||
},
|
||||
{
|
||||
"id": "L5d2c3b8016",
|
||||
"title": "reverse proxy headers — Reverse proxy headers",
|
||||
"url": "repo:///docs/reverse-proxy-headers.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Reverse proxy headers\n\nTLS를 reverse proxy에서 종료하면 Keycloak은 브라우저가 사용한 외부 origin을\n정확히 알아야 한다. 배포 예제는 다음 계약을 함께 적용한다.\n\n- nginx는 `Host`, `X-Forwarded-Host`, `X-Forwarded-Port`,\n `X-Forwarded-Proto`, `X-Forwarded-For`를 덮어쓴다.\n- Keycloak은 `KC_PROXY_HEADERS=xforwarded`로 그 헤더 형식을 명시한다.\n- `KC_HOSTNAME`은 외부 HTTPS URL로 고정하고 strict hostname 검증을 켠다.\n- Keycloak의 8080 포트는 public으로 publish하지 않고 proxy network에서만\n 접근시킨다. 신뢰되지 않은 클라이언트가 forwarded header를 직접 넣을 수\n 있으면 안 된다.\n\n`scripts/verify-reverse-proxy-headers.sh`는 양쪽 설정의 짝과 nginx 구문을\n검증한다."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/reverse-proxy-headers.md",
|
||||
"heading": "Reverse proxy headers",
|
||||
"line_start": 1,
|
||||
"line_end": 15,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 1.816984
|
||||
},
|
||||
{
|
||||
"id": "L03b6abccb3",
|
||||
"title": "google claim mapping — Google claim and identity mapping",
|
||||
"url": "repo:///docs/google-claim-mapping.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Google claim and identity mapping\n\nThe broker uses the upstream OIDC `sub` as the stable federated identity key.\nEmail is a mutable profile attribute and is never the external identity key.\n\nThe default mapping policy is:\n\n| Upstream claim | Keycloak target |\n|---|---|\n| `sub` | stable username `${ALIAS}.${CLAIM.sub}` and federated identity ID |\n| `email` | email |\n| `given_name` | first name |\n| `family_name` | last name |\n| `picture` | custom `picture` attribute |\n| `hd` | custom `hd` attribute |\n\nThe Identity Provider uses `syncMode=IMPORT`: profile values are imported on\nfirst login and later local edits are not overwritten on every login. `FORCE`\nis an explicit alternative when upstream freshness is more important.\n\n`./scripts/verify-google-claim-mapping.sh` signs in through the controllable\nOIDC realm and verifies the resulting Keycloak user, custom attributes, stable\nsubject-derived username, and federated identity record."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/google-claim-mapping.md",
|
||||
"heading": "Google claim and identity mapping",
|
||||
"line_start": 1,
|
||||
"line_end": 23,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 1.503831
|
||||
},
|
||||
{
|
||||
"id": "L0217277f31",
|
||||
"title": "account linking sub vs email — Federated account key: `sub`, not email",
|
||||
"url": "repo:///docs/account-linking-sub-vs-email.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Federated account key: `sub`, not email\n\n외부 IdP의 email은 표시·연락 속성이지 계정 식별자나 자동 연결 증명이 아니다.\nKeycloak의 federated identity는 provider alias와 provider user ID(`sub`)를\n로컬 사용자에 연결한다.\n\n정책:\n\n- 신규 identity의 email이 기존 로컬 계정과 충돌하면 기존 계정의 인증을 다시\n 요구하는 기본 First Broker Login flow를 사용한다.\n- `Automatically Set Existing User`를 production flow에 넣지 않는다.\n- upstream email 변경은 같은 `sub`의 계정 귀속을 바꾸지 않는다.\n- 마지막 로그인 수단을 unlink하는 UI에서는 먼저 다른 인증 수단을 등록하도록\n 안내한다.\n\n`verify-account-linking-sub-vs-email.sh`는 mock IdP 사용자의 email을 실제로\n변경하고 다시 로그인한다. 로컬 사용자 ID가 유지되고 federated `userId`가\nupstream `sub`와 같은지 확인한 후 원래 email을 복구한다."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/account-linking-sub-vs-email.md",
|
||||
"heading": "Federated account key: `sub`, not email",
|
||||
"line_start": 1,
|
||||
"line_end": 18,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 1.49767
|
||||
},
|
||||
{
|
||||
"id": "L4a3b756b3d",
|
||||
"title": "google idp brokering — Two verification profiles",
|
||||
"url": "repo:///docs/google-idp-brokering.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"## Two verification profiles\n\nThe default local profile imports a second Keycloak realm named `mock-google`.\nIt acts as a controllable OIDC provider and allows tests to choose claims such\nas a duplicate email, `email_verified=false`, `hd`, and `picture`. This is the\nsafe way to reproduce an unsafe email auto-link without impersonating a real\nGoogle account.\n\nThe real-Google profile is configured explicitly:\n\n1. Create a Google OAuth **Web application**.\n2. Register the exact redirect URI printed by\n `./scripts/configure-google-idp.sh`.\n3. Put `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` in ignored `.env`.\n4. Start the stack and run the configuration script.\n\nThe script writes `providerId=google`, `trustEmail=false`, minimal\n`openid profile email` scopes, and `syncMode=IMPORT` through the Keycloak Admin\nAPI. Credentials are never written to the realm export or repository.\n\nGoogle requires a public HTTPS redirect for non-local deployments. Local mock\nverification proves the Keycloak brokering boundary; a real Google login is a\nseparate credentialed acceptance profile."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/google-idp-brokering.md",
|
||||
"heading": "Two verification profiles",
|
||||
"line_start": 6,
|
||||
"line_end": 28,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 1.020519
|
||||
},
|
||||
{
|
||||
"id": "Le9a41ffd86",
|
||||
"title": "public domain tunneling — Public HTTPS domain for broker callbacks",
|
||||
"url": "repo:///docs/public-domain-tunneling.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# Public HTTPS domain for broker callbacks\n\nGoogle brokering을 반복 테스트할 때는 Cloudflare **named tunnel + 관리\n도메인**을 기본 profile로 사용한다. `trycloudflare.com` quick tunnel과\n임의 ngrok URL은 일회성 데모용이며 고정 callback으로 간주하지 않는다.\n\n설정 순서:\n\n1. `cloudflared tunnel login`\n2. `cloudflared tunnel create keycloak-patterns`\n3. 예제 config의 tunnel UUID와 credentials path를 실제 값으로 교체\n4. `cloudflared tunnel route dns keycloak-patterns auth.example.test`\n5. `cloudflared tunnel run keycloak-patterns`\n6. Keycloak `KC_HOSTNAME`과 Google redirect URI를 같은 public host로 설정\n\n컨테이너 안의 `127.0.0.1`은 cloudflared 컨테이너 자신이므로 origin에는\n`reverse-proxy:8080` 같은 Compose service DNS를 사용한다. 마지막 catch-all\ningress는 알 수 없는 hostname을 404로 끝낸다.\n\n실 tunnel 생성과 DNS 변경에는 사용자 소유 계정·도메인이 필요하므로 자동\n검증은 ingress 파일의 구조까지만 수행한다."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/public-domain-tunneling.md",
|
||||
"heading": "Public HTTPS domain for broker callbacks",
|
||||
"line_start": 1,
|
||||
"line_end": 21,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 0.729912
|
||||
},
|
||||
{
|
||||
"id": "L55212df816",
|
||||
"title": "first broker login security — First Broker Login security",
|
||||
"url": "repo:///docs/first-broker-login-security.md",
|
||||
"publisher": "local documentation corpus",
|
||||
"accessed": "",
|
||||
"facts": [
|
||||
"# First Broker Login security\n\nKeycloak 26.7.0's built-in `first broker login` flow does **not** silently\nauto-link by email. It contains:\n\n- `Create User If Unique`\n- `Handle Existing Account`\n- `Confirm link existing account`\n- email verification or re-authentication ownership proof\n\n`Automatically set existing user` is an explicit, dangerous opt-in. The local\nacceptance harness copies the built-in flow, enables AutoLink, disables the\nownership-proof branch, and signs in through a controllable OIDC account whose\nemail collides with `regular-user`. It verifies that the external identity is\nattached without proof. The harness then assigns the original built-in flow,\nrepeats the login, observes the existing-account confirmation page, and verifies\nthat no federated identity was attached.\n\nRun after the stack is healthy:\n\n```bash\n./scripts/verify-first-broker-login.sh\n```\n\nThe vulnerable flow remains only as a disabled learning artifact. The\n`mock-google` provider is always returned to the secure built-in flow at the end\nof the verification."
|
||||
],
|
||||
"notes": "Internal retrieval excerpt. Preserve provenance in the sidecar evidence map; do not copy repository paths, source IDs, access dates, or process language into reader-facing prose.",
|
||||
"source_type": "local-document",
|
||||
"status": "",
|
||||
"path": "docs/first-broker-login-security.md",
|
||||
"heading": "First Broker Login security",
|
||||
"line_start": 1,
|
||||
"line_end": 27,
|
||||
"claim_ids": [],
|
||||
"decision_ids": [],
|
||||
"priority": 0.088108
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user