Sub-scope 05 (httpclient) security/** + auth/** — manifest and probes revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5 generatedAt=2026-08-30T05:33:58+00:00 === OWNED FILES === 45b19ed9277da7a019f1b33b33280e96ecda3bf4 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/AccessToken.java 33 8f2f07b8dc8d1646a8e50de31346855f85ce84a1 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ApiKeyHeaderCredentialProvider.java 59 e43ca6b1e0e3b5470f6756de32107d8aed466983 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/BasicCredentialProvider.java 55 7d272f2742d78e61641c67541af0719723fd1442 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/CredentialProviderRegistry.java 47 4e464421d85d81c4056585691d61e3143f6793b8 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/CredentialRequest.java 66 1f9cd1536e0612f51f69cd5fdf3def0e931ec178 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/CredentialType.java 35 49b66bcdc6f21b50300fe2642841462f70ab6620 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/NoAuthCredentialProvider.java 17 d87646466ae9d824dc51abae5dc18b3008d82ea0 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/OAuth2CredentialProvider.java 128 028d1432fc9987ded1036002391a7c577d55bd30 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/OAuth2TokenCacheKey.java 31 7c1681d8eff1d75e4d3b44b8e9743d0c6c29f192 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ProxyCredentialProvider.java 36 9de59317b5bfe55d22c4bb72b12da3ebf1da8eed main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ReactiveCredentialProviderRegistry.java 79 2f94c38826b84fef42e4847424af4f84c0e05960 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ReactiveRequestCredentialProvider.java 40 fcae06235a0fd1392f306d5a9f1d9d31a757745f main/java/dev/caskeleton/adapter/outbound/httpclient/auth/RequestCredentialProvider.java 12 3ca957ac2cd00700a7258ca8451f929d2f7c344e main/java/dev/caskeleton/adapter/outbound/httpclient/auth/RequestCredentials.java 47 7dfdc6e201938f153a718113a524f29dbfa8d5a5 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/SingleFlightTokenLoader.java 148 5ea287bb9ace53e4bef53c071cffe700c11cab39 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/StaticBearerCredentialProvider.java 40 7294534b20e4bf409c3d95a546cc0d136c2d93af main/java/dev/caskeleton/adapter/outbound/httpclient/auth/UnauthorizedRetryContext.java 21 005a87161019ff41b2d01e2bebf6a62f27050f85 main/java/dev/caskeleton/adapter/outbound/httpclient/auth/UnauthorizedRetryPolicy.java 32 ac4fcf808241934a918a6a6f09a90e2fd9018e3f main/java/dev/caskeleton/adapter/outbound/httpclient/security/BodyLimitPolicy.java 56 066670590995474046a81db14eddcdb1fd9ebdc0 main/java/dev/caskeleton/adapter/outbound/httpclient/security/ClientCertificateIdentity.java 19 6be107ea25d7c44268fb02da336c26c6582e1ee3 main/java/dev/caskeleton/adapter/outbound/httpclient/security/HeaderPolicy.java 92 f5542419a3fe4d6e812245d480aeb007ea24ae80 main/java/dev/caskeleton/adapter/outbound/httpclient/security/KeyMaterialRef.java 15 171dc3e1697aae380cad944b2a76c8ae6af1c942 main/java/dev/caskeleton/adapter/outbound/httpclient/security/PreparedOperation.java 50 43785c77995e416fbe4f6b35d18f3aa8ff09c7ef main/java/dev/caskeleton/adapter/outbound/httpclient/security/PreparedTarget.java 32 c77b25e17d6c1301fecde51055a4d5e36cffeaa8 main/java/dev/caskeleton/adapter/outbound/httpclient/security/RedirectContext.java 38 1285d1aaf28ae3f367f2d79bb9988ca2604ffae3 main/java/dev/caskeleton/adapter/outbound/httpclient/security/RedirectDecision.java 30 f0b786787fbc050cb8f0e8d9abeba6b7315a2f7f main/java/dev/caskeleton/adapter/outbound/httpclient/security/RedirectEvaluator.java 28 6aed71021b55d5d1dfe08de7018e5faeac255fe1 main/java/dev/caskeleton/adapter/outbound/httpclient/security/RedirectPolicy.java 40 94df5c655ea8692dbf0e255dcaf1d5263da9de08 main/java/dev/caskeleton/adapter/outbound/httpclient/security/SensitiveHeaderStripper.java 68 dfacd90bd51cbe577ae4e494fc8ba6ec409c6ce9 main/java/dev/caskeleton/adapter/outbound/httpclient/security/SslContextMaterial.java 40 b06fab3702a39730b4ef29b8c8d7adb9fd41f6e3 main/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsMaterialProvider.java 176 2bb1808f232b47eb3adfa624b572877e602603fe main/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsPolicyValidator.java 60 f46c98cc02a47c3fa6f893583d3a244d22bb1b98 main/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsProfile.java 53 827602fd445f1dafbaa497e503085f99dc175215 main/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsProfileId.java 16 1d2305691c08de607f7184196d3e7565b74c1fce main/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsRuntimeRotationCoordinator.java 78 2ff2ae0f15bf65227056807964b7259bcf66b1d1 main/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsViolation.java 18 c7fbe0c84b7f6a9869b578c2c2a1bc1f0b773abd main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustMaterialRef.java 30 893051f246483ecf711513b7c21e7db1199e31db main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedTargetPolicy.java 176 7e9120e1e75e9c71c648cccf76519d7f324df067 main/java/dev/caskeleton/adapter/outbound/httpclient/security/UriTemplateExpander.java 31 19a410d8b58e3ea2c5d96a41a1a72bd2975951f2 test/java/dev/caskeleton/adapter/outbound/httpclient/auth/SingleFlightTokenLoaderTest.java 73 78dafebd6089c54e0570ef8f7eb9de4db52a2cc6 test/java/dev/caskeleton/adapter/outbound/httpclient/auth/UnauthorizedRetryPolicyTest.java 61 db79b2c0d0c099886a72efb6f23dc2ade70ef1b9 test/java/dev/caskeleton/adapter/outbound/httpclient/security/MutualTlsHandshakeContractTest.java 172 259568f2f1d3f9f2cea74341edf9a4f107fc81c0 test/java/dev/caskeleton/adapter/outbound/httpclient/security/RedirectEvaluatorTest.java 101 f1c7e41165464d192cbd552bed1269261ace3a6e test/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsPolicyValidatorTest.java 58 e77b752a85b380b537c83e604c8288254f80a756 test/java/dev/caskeleton/adapter/outbound/httpclient/security/TlsRuntimeRotationCoordinatorTest.java 114 104df751c46e88bbb38bf9b5f0262d3022fbd316 test/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedRequestPolicyTest.java 161 main: 39 test: 7 === 8.1 자격증명이 toString으로 새는 타입이 있는가 === $ git grep -Ln 'public String toString' -- 'adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ApiKeyHeaderCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/BasicCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/CredentialProviderRegistry.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/CredentialType.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/NoAuthCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/OAuth2CredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/OAuth2TokenCacheKey.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ProxyCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ReactiveCredentialProviderRegistry.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/ReactiveRequestCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/RequestCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/SingleFlightTokenLoader.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/StaticBearerCredentialProvider.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/UnauthorizedRetryContext.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/UnauthorizedRetryPolicy.java exit=0 $ grep -rn 'REDACTED' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security | head adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/RequestCredentials.java:45: + ", values=REDACTED]"; adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/auth/AccessToken.java:31: return "AccessToken[REDACTED, expiresAt=" + expiresAt + "]"; exit=0 === 8.2 UNBOUND 가짜 메타데이터의 production 사용 === $ grep -n 'UNBOUND' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security/HeaderPolicy.java 36: private static final HttpFailureMetadata UNBOUND = 59: return validate(input, UNBOUND); exit=0 $ git grep -rn '\.validate(' -- 'adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient' | grep -i header | head adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/dynamic/DefaultDynamicTargetGateway.java:156: .validate(operation.headers(), metadata); adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedTargetPolicy.java:80: .validate(operation.headers(), metadata); exit=0 === 8.3 SSRF 방어 지점 전수 === $ git grep -n 'requireAllowedTarget\|requireAllowedOrigin' -- 'adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/restclient/BlockingAttemptExecutor.java:145: runtime.targetPolicy()::requireAllowedTarget); adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedTargetPolicy.java:76: requireAllowedOrigin(target, metadata); adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedTargetPolicy.java:162: public void requireAllowedTarget(java.net.URI target, HttpFailureMetadata metadata) { adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedTargetPolicy.java:163: requireAllowedOrigin(PreparedTarget.of(target, target.getPath()), metadata); adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/security/TrustedTargetPolicy.java:166: private void requireAllowedOrigin(PreparedTarget target, HttpFailureMetadata metadata) { exit=0 $ git grep -ln 'IpAddressClassifier' -- 'adapter/outbound/httpclient/src/main' adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/dynamic/IpAddressClassifier.java adapter/outbound/httpclient/src/main/java/dev/caskeleton/adapter/outbound/httpclient/dynamic/ValidatedDnsResolver.java exit=0 === 8.4 test === $ git ls-files 'adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/security' 'adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/auth' | xargs -n1 basename SingleFlightTokenLoaderTest.java UnauthorizedRetryPolicyTest.java MutualTlsHandshakeContractTest.java RedirectEvaluatorTest.java TlsPolicyValidatorTest.java TlsRuntimeRotationCoordinatorTest.java TrustedRequestPolicyTest.java exit=0 $ git grep -h ' void [a-z]' -- 'adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/security' 'adapter/outbound/httpclient/src/test/java/dev/caskeleton/adapter/outbound/httpclient/auth' | sed 's/^ *//' void concurrentRequestsShareOneTokenRefresh() throws Exception { void tokenValueIsNeverRenderedInTextForm() { void denies401ReplayForOneShotPost() { void allowsExactlyOneReplayForASafeReplayableOperation() { void allowsAKeyedWriteOnlyWhenAuthFailedBeforeAnySideEffect() { void aClientCertificateSatisfiesAServerThatRequiresOne() throws Exception { void aMissingClientCertificateCannotReachTheUpstream() throws Exception { void aHostnameMismatchIsAPermanentTlsFailure() throws Exception { void anExpiredCertificateIsAPermanentTlsFailure() throws Exception { void anUntrustedAuthorityIsAPermanentTlsFailure() throws Exception { void rejects307WhenBodyIsOneShot() { void rejectsWhenRedirectsAreDisabledOrHopsAreExhausted() { void rejectsCrossOriginUnlessExplicitlyAllowed() { void followsAReplayableSameOriginHop() { void stripsCredentialsOnCrossOriginRedirect() { void rejectsTrustAllAndHostnameVerificationDisablement() { void rejectsLegacyProtocolVersions() { void acceptsAStandardProfile() { void tlsProfileHasNoRepresentationForTrustAll() { void swapsRuntimeWhenCertificateIdentityChanges() { void rotationTouchesOnlyTheProfilesThatUseTheRotatedCertificate() { void rejectsAbsoluteUriInTrustedGenericGateway() { void rejectsHeaderInjection() { void rejectsPlatformOwnedHeaderOverride() { void allowsIdempotencyKeyOnlyWhenTheOperationDeclaresIt() { void rejectsKnownBodyLargerThanProfileLimit() { void encodesTemplateVariablesPerComponent() { void carriesProfileBudgetsForwardToTheExecutor() { void aRegisteredIdempotencyKeyIsRenderedAsAHeader() { void aCallerSuppliedIdempotencyHeaderIsRefused() { void aKeyWhoseRequirementWasNotRegisteredIsRefused() { exit=0