Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/a19-f008-acl.txt
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

126 lines
8.1 KiB
Plaintext

BrokerAclManifest.java : 141 줄
# 자바독이 적어 둔 두 검사
BrokerAclManifest.java:12 * <p>Written down so the grant can be reviewed and diffed rather than discovered from a broker
BrokerAclManifest.java:13 * dump. The manifest is what the platform checks itself against at startup: a runtime that holds
BrokerAclManifest.java:14 * more than it declares is a finding, because the extra permission is the one nobody reasoned
BrokerAclManifest.java:15 * about.
BrokerAclManifest.java:16 *
BrokerAclManifest.java:17 * <p>Destructive permissions are named separately from ordinary ones. {@code DELETE_TOPIC} and
BrokerAclManifest.java:18 * {@code PURGE} are not "write, but more"; they destroy data an application can never restore, so
BrokerAclManifest.java:19 * an application runtime declaring one is rejected outright.
BrokerAclManifest.java:20 *
# 그 두 성질에 대응하는 코드가 이 타입 안에 있다
BrokerAclManifest.java:94 public List<Grant> destructiveGrants() {
BrokerAclManifest.java:95 return grants.stream().filter(grant -> grant.operation().isDestructive()).toList();
BrokerAclManifest.java:98 /**
BrokerAclManifest.java:99 * Refuses a manifest that gives an application runtime destructive power.
BrokerAclManifest.java:100 *
BrokerAclManifest.java:101 * @throws MessagingConfigurationException when a destructive grant is declared
BrokerAclManifest.java:102 */
BrokerAclManifest.java:103 public void requireApplicationRuntime() {
BrokerAclManifest.java:104 List<Grant> destructive = destructiveGrants();
BrokerAclManifest.java:105 if (!destructive.isEmpty()) {
BrokerAclManifest.java:106 throw new MessagingConfigurationException(
BrokerAclManifest.java:107 "APPLICATION_HOLDS_DESTRUCTIVE_GRANT",
BrokerAclManifest.java:108 "principal %s declares %s, which an application runtime must never hold"
BrokerAclManifest.java:109 .formatted(principal, destructive.stream().map(Grant::operation).toList()));
BrokerAclManifest.java:110 }
BrokerAclManifest.java:111 }
BrokerAclManifest.java:113 /**
BrokerAclManifest.java:114 * Reports the permissions the runtime holds but never declared.
BrokerAclManifest.java:115 *
BrokerAclManifest.java:116 * <p>Excess is the finding, not the shortfall: a missing grant fails loudly on first use, while
BrokerAclManifest.java:117 * an undeclared extra one sits unnoticed until it is abused.
BrokerAclManifest.java:118 *
BrokerAclManifest.java:119 * @param observed the grants the broker actually reports for this principal
BrokerAclManifest.java:120 * @return the observed grants that this manifest does not declare
BrokerAclManifest.java:121 */
BrokerAclManifest.java:122 public Set<Grant> undeclared(Set<Grant> observed) {
BrokerAclManifest.java:123 Objects.requireNonNull(observed, "observed must not be null");
BrokerAclManifest.java:124 Set<Grant> extra = new LinkedHashSet<>(observed);
BrokerAclManifest.java:125 extra.removeAll(Set.copyOf(grants));
BrokerAclManifest.java:126 return Set.copyOf(extra);
BrokerAclManifest.java:127 }
BrokerAclManifest.java:128
BrokerAclManifest.java:130 * Reports the declared permissions the broker does not actually grant.
BrokerAclManifest.java:131 *
BrokerAclManifest.java:132 * @param observed the grants the broker actually reports for this principal
BrokerAclManifest.java:133 * @return the declared grants that are missing
BrokerAclManifest.java:134 */
BrokerAclManifest.java:135 public Set<Grant> missing(Set<Grant> observed) {
BrokerAclManifest.java:136 Objects.requireNonNull(observed, "observed must not be null");
BrokerAclManifest.java:137 Set<Grant> absent = new LinkedHashSet<>(grants);
BrokerAclManifest.java:138 absent.removeAll(observed);
BrokerAclManifest.java:139 return Set.copyOf(absent);
BrokerAclManifest.java:140 }
# 간결 생성자는 그 검사를 하지 않는다
BrokerAclManifest.java:81 public BrokerAclManifest {
BrokerAclManifest.java:82 Objects.requireNonNull(grants, "grants must not be null");
BrokerAclManifest.java:83 if (principal == null || principal.isBlank()) {
BrokerAclManifest.java:84 throw new IllegalArgumentException("principal must not be blank");
BrokerAclManifest.java:85 }
BrokerAclManifest.java:86 grants = List.copyOf(grants);
BrokerAclManifest.java:87 }
# 그 세 메서드를 부르는 자리 전부
main · BrokerAclManifest.java:94 public List<Grant> destructiveGrants() {
main · BrokerAclManifest.java:103 public void requireApplicationRuntime() {
main · BrokerAclManifest.java:104 List<Grant> destructive = destructiveGrants();
test · CredentialRuntimeRegistryTest.java:181 assertThatThrownBy(manifest::requireApplicationRuntime)
test · CredentialRuntimeRegistryTest.java:200 assertThat(manifest.undeclared(Set.of(declared, extra)))
그중 BrokerAclManifest.java 밖의 main 코드 :
0 건
# 이 타입을 만들거나 받는 프로덕션 코드
main 에서 0 건
자기 파일 밖에서 이 이름이 나오는 파일 수 : 1
messaging/messaging-security/src/test/java/dev/caskeleton/messaging/security/CredentialRuntimeRegistryTest.java
그 시험이 단언하는 것 :
CredentialRuntimeRegistryTest.java:167 void anApplicationRuntimeMayNotHoldADestructiveGrant() {
CredentialRuntimeRegistryTest.java:181 assertThatThrownBy(manifest::requireApplicationRuntime)
CredentialRuntimeRegistryTest.java:187 void aGrantTheBrokerHoldsButNobodyDeclaredIsTheFinding() {
CredentialRuntimeRegistryTest.java:200 assertThat(manifest.undeclared(Set.of(declared, extra)))
# 파괴적 권한이 값으로 표시되는 방식
BrokerAclManifest.java:49 public enum Operation {
BrokerAclManifest.java:51 WRITE(false),
BrokerAclManifest.java:53 READ(false),
BrokerAclManifest.java:55 DESCRIBE(false),
BrokerAclManifest.java:57 CREATE(false),
BrokerAclManifest.java:59 ALTER(true),
BrokerAclManifest.java:61 DELETE(true),
BrokerAclManifest.java:63 PURGE(true);
# 기동 시점 검증으로 감싸인 프로파일은 셋이다
KafkaMessagingAutoConfiguration.java:59 return new StartupProfileValidation<>(
KafkaMessagingAutoConfiguration.java:60 () ->
KafkaMessagingAutoConfiguration.java:61 java.util.stream.Stream.concat(
KafkaMessagingAutoConfiguration.java:62 compiled.kafkaBrokers().stream(), profiles.orderedStream())
MessagingCoreAutoConfiguration.java:221 return new StartupProfileValidation<>(
MessagingCoreAutoConfiguration.java:222 () ->
MessagingCoreAutoConfiguration.java:223 java.util.stream.Stream.concat(compiled.security().stream(), profiles.orderedStream())
MessagingCoreAutoConfiguration.java:224 .toList(),
RabbitMessagingAutoConfiguration.java:55 return new StartupProfileValidation<>(
RabbitMessagingAutoConfiguration.java:56 () ->
RabbitMessagingAutoConfiguration.java:57 java.util.stream.Stream.concat(
RabbitMessagingAutoConfiguration.java:58 compiled.rabbitBrokers().stream(), profiles.orderedStream())
# 파괴 연산 자체를 막는 다른 장치
main · DestructiveMessagingAdmin.java:21 public interface DestructiveMessagingAdmin {
main · MessagingAdminService.java:21 * <p>Destructive operations live in {@link DestructiveMessagingAdmin}, a separate interface that an
main · MessagingAdminAutoConfiguration.java:22 * <p>{@link dev.caskeleton.messaging.admin.runtime.DestructiveMessagingAdmin} is deliberately
그 인터페이스를 구현하는 main 클래스 : 0 건
# 브로커에 권한을 질의하는 코드
describeAcls 0 파일
DescribeAclsResult 0 파일
AclBinding 0 파일
createAcls 0 파일
AclOperation 0 파일
Authorizer 0 파일
listPermissions 0 파일
checkPermissions 0 파일
그 0 들의 의미를 정하는 사실 — Kafka AdminClient 자체의 소스 세트별 분포 :
test : 5 파일