Series MapLesson 02 / 35
Start HereOrdered learning track

Learn Java Security Cryptography Integrity Part 002 Threats Assets Trust Boundaries

21 min read4174 words
PrevNext
Lesson 0235 lesson track0106 Start Here

title: Learn Java Security, Cryptography and Integrity - Part 002 description: Threat, asset, actor, data flow, trust boundary, abuse case, and security invariant modeling for Java enterprise systems. series: learn-java-security-cryptography-integrity seriesTitle: Learn Java Security, Cryptography and Integrity order: 2 partTitle: Threats, Assets, Trust Boundaries tags:

  • java
  • security
  • threat-modeling
  • trust-boundary
  • secure-design date: 2026-06-30

Part 002 — Threats, Assets, Trust Boundaries

Target part ini: Anda mampu membaca sistem Java sebagai sekumpulan asset, actor, data flow, trust boundary, dan abuse path. Output akhirnya bukan diagram cantik, tetapi daftar security invariant dan control yang bisa diimplementasikan.

Threat modeling sering gagal karena terlalu formal di awal. Engineer menggambar diagram, menempelkan label STRIDE, lalu berhenti. Hasilnya tidak mengubah desain, tidak menghasilkan test, dan tidak masuk ke backlog.

Kita akan memakai threat modeling secara praktis:

system understanding -> asset discovery -> boundary discovery -> abuse path -> invariant -> control -> validation

OWASP Threat Modeling Cheat Sheet merangkum threat modeling dalam beberapa langkah utama: decomposition, threat identification/ranking, mitigations, dan review/validation. Dalam seri ini, setiap langkah harus menghasilkan artefak engineering yang actionable: policy code, test case, configuration, alert, audit field, atau deployment control.

Referensi:


1. Threat Modeling: Definisi yang Berguna untuk Engineer

Threat modeling adalah proses menjawab:

  1. Apa yang sedang kita bangun?
  2. Apa yang harus dilindungi?
  3. Siapa atau apa yang bisa berinteraksi dengan sistem?
  4. Di mana asumsi trust berubah?
  5. Apa yang bisa salah?
  6. Control apa yang mengurangi risk?
  7. Bagaimana kita membuktikan control bekerja?

Definisi yang terlalu akademis sering tidak membantu. Definisi praktis:

Threat modeling adalah desain review yang memaksa kita melihat sistem dari sudut pandang penyalahgunaan, bukan hanya happy path.

Dalam Java enterprise, threat modeling harus menjangkau:

  • HTTP API,
  • background worker,
  • scheduler,
  • message consumer,
  • database transaction,
  • file/object storage,
  • authentication provider,
  • authorization policy,
  • audit log,
  • cryptographic keys,
  • build pipeline,
  • deployment runtime,
  • admin/operator workflow,
  • integration partner,
  • third-party SaaS.

Jangan hanya threat-model controller. Banyak compromise terjadi di job, event consumer, import/export pipeline, migration script, atau admin endpoint.


2. Vocabulary Inti

2.1 Asset

Asset adalah sesuatu yang bernilai dan perlu dilindungi.

Asset bukan hanya data. Dalam sistem Java, asset bisa berupa:

Asset TypeContohSecurity Concern
Business datacase record, customer profile, payment instructionconfidentiality, integrity, privacy
Sensitive actionapprove case, waive fee, reset passwordauthorization, non-repudiation, auditability
Identity datauser id, role, group, tenant, assurance levelimpersonation, privilege escalation
SecretAPI key, signing key, DB password, refresh tokenleakage, misuse, rotation
Cryptographic keyDEK, KEK, private key, HMAC secretkey lifecycle, compromise response
Audit eventapproval log, login event, policy decisiontampering, retention, evidentiary quality
Message/eventdomain event, integration event, webhookreplay, forgery, ordering
Build artifactJAR, container image, SBOM, provenancesupply-chain integrity
Runtime capabilitynetwork egress, file write, cloud IAM permissionlateral movement, blast radius
Availabilityapproval workflow, payment channel, regulatory portalDoS, dependency failure

A mature engineer tidak hanya bertanya “data apa yang rahasia?” tetapi juga “action apa yang irreversible?” dan “evidence apa yang harus dipercaya nanti?”

2.2 Actor

Actor adalah entitas yang dapat melakukan aksi atau memengaruhi sistem.

Actor bisa berupa:

  • anonymous user,
  • authenticated user,
  • admin,
  • support operator,
  • auditor,
  • service account,
  • scheduled job,
  • message broker,
  • partner system,
  • CI runner,
  • developer,
  • dependency maintainer,
  • cloud provider identity,
  • attacker controlling a legitimate account,
  • attacker controlling network path,
  • attacker controlling dependency artifact.

Perhatikan dua hal:

  1. Actor tidak selalu manusia.
  2. Actor tidak selalu malicious dari awal.

Banyak insiden terjadi dari legitimate actor dengan privilege terlalu luas, credential bocor, atau confused deputy.

2.3 Threat

Threat adalah skenario yang dapat merusak asset.

Contoh:

A compromised support account exports all cases across tenants.
A partner replays yesterday's webhook to revert a case status.
A message consumer accepts unsigned events from a shared broker topic.
A developer accidentally commits signing key to repository.
A stale JWT remains valid after user deactivation.
A malicious file upload is served back with executable content type.
A build plugin injects code during compilation.

Threat yang baik memiliki struktur:

Actor + capability + path + asset + impact

Contoh buruk:

JWT attack.

Contoh lebih baik:

An attacker with a stolen refresh token can obtain new access tokens after the user is disabled because refresh token revocation is not checked during rotation.

2.4 Vulnerability

Vulnerability adalah kelemahan yang membuat threat bisa terjadi.

Contoh vulnerability:

  • object-level authorization tidak ada,
  • token audience tidak divalidasi,
  • alg header JWT dipercaya tanpa allowlist,
  • custom TrustManager menerima semua certificate,
  • file path dibangun dari input user tanpa canonical path check,
  • message event tidak punya signature atau source authentication,
  • audit event bisa diupdate,
  • build pipeline mengambil dependency dari repository publik tanpa verification,
  • secret disimpan di config file.

2.5 Control

Control adalah mekanisme yang menurunkan risk.

Control bisa bersifat:

Control TypeContoh
Preventiveauthorization check, input validation, mTLS, policy-as-code
Detectiveaudit log, anomaly alert, SCA scanner, auth failure metric
Correctivekey rotation, token revocation, incident rollback
Compensatingmanual approval, break-glass audit, temporary allowlist
Deterrentlegal notice, admin action recording, dual control

Engineer sering terlalu fokus preventive control. Sistem enterprise juga perlu detective dan corrective control karena tidak semua hal dapat dicegah sempurna.

2.6 Trust Boundary

Trust boundary adalah titik di mana data, identity, privilege, or control berpindah dari satu trust assumption ke assumption lain.

Contoh:

  • internet ke API gateway,
  • API gateway ke Java service,
  • Java service ke database,
  • service A ke service B,
  • application ke KMS,
  • CI pipeline ke artifact repository,
  • admin UI ke internal privileged API,
  • message broker ke consumer,
  • object storage ke download endpoint,
  • partner webhook ke domain event handler.

Trust boundary bukan selalu network boundary. Boundary bisa terjadi dalam satu process:

  • controller ke service,
  • DTO ke domain command,
  • principal claim ke authorization decision,
  • serialized payload ke object graph,
  • file bytes ke parsed document,
  • string path ke filesystem object,
  • unsigned event ke business fact.

3. Mengapa Trust Boundary Lebih Penting dari Component Diagram

Component diagram menunjukkan struktur. Trust boundary menunjukkan perubahan asumsi.

Diagram komponen tanpa boundary:

Diagram ini kurang berguna untuk security karena tidak menunjukkan mana yang trusted, mana yang hostile, dan mana yang privileged.

Versi lebih baik:

Sekarang kita bisa bertanya:

  • Apakah gateway boleh dipercaya untuk identity?
  • Apakah Java service memvalidasi ulang token atau hanya menerima header?
  • Apakah DB role terlalu luas?
  • Apakah broker topic shared dengan service lain?
  • Apakah worker memverifikasi event source?
  • Apakah audit store append-only?

4. Proses Threat Modeling yang Efektif

Gunakan proses 7 langkah.

Ya, diagram menunjukkan 8 node. Langkah ke-8 adalah feedback, bukan discovery. Dalam praktik, threat model tanpa validation adalah dugaan.


5. Step 1 — Define Scope

Scope menjawab: “apa yang sedang kita threat-model?”

Scope buruk:

Threat model aplikasi case management.

Scope baik:

Threat model untuk workflow approval high-risk regulatory case dari request API sampai audit event dan domain event dipublish.

Scope harus menyebut:

  • use case,
  • entry point,
  • exit point,
  • data store,
  • external dependency,
  • environment,
  • out-of-scope eksplisit.

Contoh:

## Scope

In scope:
- POST /cases/{id}/approval
- authentication context from OIDC provider
- object-level authorization
- case state transition REVIEWED -> APPROVED
- audit event append
- domain event publish to Kafka
- notification worker consuming approval event

Out of scope:
- user registration
- case creation
- payment integration
- document upload

Scope yang tajam mencegah threat modeling menjadi diskusi tanpa ujung.


6. Step 2 — Map Actors

Buat daftar actor dengan capability dan trust level.

ActorTrust LevelCapabilityConcern
Anonymous internet userUntrustedcall public endpointenumeration, injection, DoS
Authenticated reviewerPartially trustedapprove assigned casesover-approval, tenant escape
Case creatorPartially trustedsubmit evidencemaker-checker bypass
Support operatorPrivileged humanassist users, view limited dataprivilege abuse, social engineering
AdminHighly privilegedmanage policy/configtoxic privilege, audit bypass
Case API serviceInternal serviceread/write casesconfused deputy
Notification workerInternal serviceconsume eventsforged/replayed events
OIDC providerExternal trusted dependencyissue tokensstale claims, outage
KMSExternal trusted dependencyunwrap/generate keyskey availability, misuse
CI runnerBuild-time actorproduce artifactsupply-chain compromise

6.1 Actor State Matters

Actor yang sama bisa berada dalam state berbeda:

user active
user suspended
user deleted
user with stale session
user with stolen token
user after MFA
user before MFA
user acting through delegation
user acting through support impersonation

Authorization yang matang tidak hanya melihat role, tetapi juga actor state.

Contoh:

public record ActorContext(
        UserId userId,
        TenantId tenantId,
        Set<Role> roles,
        Set<Permission> permissions,
        AuthStrength authStrength,
        Instant authenticatedAt,
        boolean active,
        Optional<DelegationContext> delegation
) {}

Jangan jadikan actor sebagai String username jika domain Anda butuh security decision yang kaya.


7. Step 3 — Identify Assets

Asset discovery harus lebih detail daripada “database”.

Untuk workflow approval case:

AssetWhy It MattersSecurity Property
Case databasis keputusan regulatorintegrity, confidentiality
Approval actionmengubah status legal/operasionalauthorization, non-repudiation-like evidence
Case state transitionmenentukan workflowintegrity, consistency
Actor identitydasar accountabilityauthenticity, freshness
Authorization policymenentukan siapa boleh apaintegrity, change control
Audit eventbukti investigasitamper evidence, completeness
Domain eventmemicu downstream actionauthenticity, replay resistance
Signing/MAC keymelindungi event/requestconfidentiality, access control, rotation
Notification contentbisa mengandung PIIconfidentiality, minimization
Build artifactmenjalankan logic approvalprovenance, integrity

7.1 Asset Criticality

Gunakan skala sederhana:

LevelMeaningExample
Criticalcompromise bisa menyebabkan legal/regulatory/financial damage besarapproval action, signing key, audit log
Highcompromise berdampak serius tapi bisa dikompensasicase evidence, export data
Mediumcompromise terbatasnotification preference
Lowpublic/non-sensitivestatic public content

Asset criticality menentukan control. Tidak semua data butuh encryption field-level. Tetapi approval action mungkin butuh step-up auth dan four-eyes control.


8. Step 4 — Draw Data Flows

Data flow menjelaskan bagaimana data bergerak, berubah bentuk, dan menjadi fakta.

Contoh flow approval:

Untuk setiap arrow, tanya:

  • Data apa yang lewat?
  • Apakah data trusted?
  • Apakah identity ikut terbawa?
  • Apakah ada replay risk?
  • Apakah ada tampering risk?
  • Apakah ada ordering/freshness requirement?
  • Apakah kegagalan dependency membuat sistem fail open?

8.1 Data Transformation Points

Security sering gagal di titik transformasi:

FromToRisk
HTTP stringUUIDIDOR jika dianggap authorized
JWT claimprincipalstale/forged/misvalidated claim
DTOdomain commandmissing invariant
domain eventKafka messageforged/replayed event
uploaded bytesstored objectmalware/content-type confusion
JSON/XMLobject graphparser abuse/deserialization risk
database rowaudit evidencetampering atau incomplete context

9. Step 5 — Mark Trust Boundaries

Trust boundary harus eksplisit.

Contoh boundary list:

Boundary IDBoundaryAssumption ChangeRequired Control
TB-01Internet -> API Gatewayhostile network to controlled edgeTLS, rate limit, WAF where useful
TB-02Gateway -> Java APIforwarded identity becomes app contexttoken/header validation, trusted proxy config
TB-03Controller -> Domain Servicerequest DTO becomes commandvalidation, canonicalization, invariant check
TB-04Domain -> DBproposed state becomes durable facttransaction, optimistic lock, DB constraints
TB-05Domain -> Audit Storeevent becomes evidenceappend-only, hash chain/signing, retention
TB-06API -> Brokerlocal fact becomes distributed messagesigning/MAC, schema, idempotency key
TB-07Broker -> Workerexternal message becomes action triggersignature verification, replay defense
TB-08CI -> Artifact Repobuild output becomes deployable artifactsigning, provenance, SBOM, access control

9.1 Hidden Trust Boundaries in Java Code

Be careful with these hidden boundaries:

9.1.1 Principal Boundary

String tenantId = jwt.getClaim("tenant_id");

Questions:

  • Is the token signature verified?
  • Is issuer trusted?
  • Is audience correct?
  • Is token expired?
  • Is tenant claim authoritative?
  • Can tenant membership change before token expiry?

9.1.2 Repository Boundary

caseRepository.findById(caseId)

Question:

  • Is object-level authorization enforced?

Prefer repository methods that make tenant boundary explicit when possible:

caseRepository.findByIdAndTenantId(caseId, actor.tenantId())

But do not stop there. Tenant filter is not complete authorization; it is one boundary control.

9.1.3 Event Consumer Boundary

@KafkaListener(topics = "case-events")
public void consume(CaseApprovedEvent event) {
    notificationService.notify(event.caseId());
}

Questions:

  • Who can publish to the topic?
  • Is schema validated?
  • Is event signed or authenticated?
  • Is event idempotent?
  • Can old event be replayed?
  • Does consumer check event version/order?

9.1.4 File Boundary

Path target = uploadRoot.resolve(fileName);

Questions:

  • Was fileName canonicalized?
  • Can it escape directory?
  • Is content type trusted from client?
  • Is stored object executable or served inline?
  • Is malware scanning asynchronous or blocking?

10. Step 6 — Generate Threats

Kita bisa memakai STRIDE sebagai prompt, bukan sebagai tujuan akhir.

STRIDEPertanyaanJava Enterprise Example
SpoofingBisa berpura-pura menjadi actor lain?forged JWT, trusted header spoofing, stolen service token
TamperingBisa mengubah data/event/config/artifact?unsigned Kafka event, mutable audit row, modified JAR
RepudiationBisa menyangkal aksi?audit log incomplete, no actor/session/policy version
Information DisclosureBisa melihat data yang tidak boleh?IDOR, verbose error, log leaking secret
Denial of ServiceBisa membuat sistem unavailable?expensive parser input, auth service exhaustion
Elevation of PrivilegeBisa mendapat privilege lebih tinggi?missing object authz, role confusion, CI token abuse

10.1 Threat Template

Gunakan format ini:

## Threat: <short title>

Actor:
Capability:
Asset:
Path:
Boundary:
Impact:
Existing Controls:
Missing Controls:
Proposed Invariant:
Validation:
Residual Risk:

Contoh:

## Threat: Cross-Tenant Case Approval

Actor:
Authenticated reviewer from Tenant A.

Capability:
Can call approval endpoint with arbitrary case UUID.

Asset:
Case approval action and case state integrity for Tenant B.

Path:
POST /cases/{caseId}/approval -> load case by id -> approve.

Boundary:
External case id becomes internal case object.

Impact:
Unauthorized approval, regulatory breach, audit trust loss.

Existing Controls:
User is authenticated and has APPROVE_CASE role.

Missing Controls:
Object-level tenant authorization, maker-checker rule, state check.

Proposed Invariant:
A user can approve only a case in the same tenant, not created by the user,
with required permission for category and valid state REVIEWED.

Validation:
Integration test: Tenant A reviewer cannot approve Tenant B case even if UUID is known.

Residual Risk:
Compromised same-tenant reviewer account can still attempt malicious approval;
mitigated by maker-checker, step-up auth, audit, anomaly detection.

11. Step 7 — Derive Invariants and Controls

Threats harus berubah menjadi invariants.

Threat:

Attacker replays old webhook and changes case status.

Invariant:

No webhook event may change case state unless it has a valid signature,
fresh timestamp, unused nonce/event id, expected partner id, and monotonic case version.

Controls:

  • HMAC or digital signature,
  • canonical request format,
  • timestamp freshness window,
  • nonce/event id replay cache,
  • partner-specific key,
  • state/version check,
  • idempotency handling,
  • audit record for accept/reject,
  • alert on repeated invalid signatures.

Validation:

  • valid request accepted,
  • stale timestamp rejected,
  • reused nonce rejected,
  • changed body rejected,
  • wrong partner key rejected,
  • lower case version rejected,
  • duplicate event returns idempotent response.

11.1 Control Placement

Control harus ditempatkan pada boundary yang benar.

ThreatWrong Control PlacementBetter Placement
Cross-tenant accessHide button in UIenforce in service/domain/repository query
Forged eventtrust Kafka topic nameverify event signature/producer identity in consumer
Secret leakagetell devs not to logstructured redaction + logging policy + scanner
Invalid state transitionfrontend disables actiondomain state machine + DB constraint/optimistic lock
JWT misusedecode token manually in business codecentralized validated principal + explicit authz context
Upload malwarecheck filename extensioninspect content, store safely, scan, serve with safe headers

Security control di UI bisa meningkatkan UX, tetapi bukan enforcement utama.


12. Data Flow Diagram untuk Java Service

Gunakan level yang cukup detail untuk melihat boundary.

Boundary questions:

  1. Is Gateway allowed to inject identity headers?
  2. Can clients bypass Gateway and hit Java service directly?
  3. Does Controller trust request fields that should come from token?
  4. Does Authz check object and tenant, or only role?
  5. Can Domain update DB without audit write?
  6. Is AuditStore append-only or merely another mutable table?
  7. Does EventSigner sign canonical event or serialized incidental JSON?
  8. Can Broker accept messages from untrusted producer?
  9. What happens if KMS is down?

13. Java-Oriented Threat Catalog

Berikut katalog awal yang akan sering muncul di seri ini.

13.1 Identity and Token Threats

ThreatSymptomControl
Token audience ignoredtoken for service A accepted by service Bvalidate aud
Issuer confusiontoken from dev/rogue issuer acceptedstrict issuer allowlist
Algorithm confusionweak/unexpected JWT alg acceptedalgorithm allowlist, library config
Stale authorizationrole changed but token still validshort TTL, introspection, policy check
Session fixationattacker sets session id before loginrotate session after auth
Weak account recoveryattacker resets accountrecovery risk model, step-up verification

13.2 Authorization Threats

ThreatSymptomControl
IDORuser accesses object by guessed IDobject-level authz
Tenant escapeglobal query by idtenant-scoped query + authz
Confused deputyservice uses own privilege for user actionpropagate actor intent, policy evaluation
Role explosionroles become unreviewablepermission model + policy ownership
Missing state authzaction allowed in invalid workflow statedomain invariant/state machine
Admin overreachadmin can bypass all control silentlydual control, break-glass audit

13.3 Crypto and Integrity Threats

ThreatSymptomControl
Random token predictableuses RandomSecureRandom
Encryption without authciphertext tampering possibleAEAD such as AES-GCM where appropriate
Key hardcodedsecret in repository/configKMS/Vault, secret scanning
Nonce reuserepeated AES-GCM IV under same keynonce generation discipline
Hash mistaken for proofattacker recalculates hashMAC/signature
Unsigned eventconsumer trusts event blindlysignature/MAC + replay defense

13.4 Java Runtime and Supply Chain Threats

ThreatSymptomControl
Dependency confusioninternal artifact name pulled from public reporepository policy, verification
Malicious build pluginplugin executes during buildplugin pinning, provenance, isolated CI
Overprivileged containerapp runs root with broad FS/networknon-root, read-only FS, egress control
Secret in heap dumpproduction dump contains credentialsdump policy, redaction, secret handling
Trust-all TLScustom TrustManager disables validationstandard JSSE validation, tests
Log injectionattacker controls log linesstructured logging, encoding

14. Risk Ranking without Theater

Risk ranking sering menjadi permainan angka. Kita butuh cukup struktur untuk prioritas, bukan kepalsuan presisi.

Gunakan faktor:

FactorQuestion
ImpactJika terjadi, apa kerusakannya?
LikelihoodSeberapa realistis path-nya?
ExposureApakah reachable dari internet, internal, atau privileged-only?
ExploitabilityButuh skill/credential/position apa?
Blast RadiusSatu user, satu tenant, semua tenant, semua system?
DetectabilityApakah kita akan tahu?
ReversibilityApakah efeknya bisa dibatalkan?
Regulatory WeightApakah berdampak legal/compliance?

Contoh scoring ringan:

Risk = Impact(1-5) × Exposure(1-5) × Exploitability(1-5) × BlastRadius(1-5)

Namun skor tidak boleh menggantikan reasoning. Dua risk dengan skor sama bisa punya prioritas berbeda karena satu risk irreversible atau punya konsekuensi regulator.

14.1 Example Ranking

ThreatImpactExposureExploitabilityBlast RadiusNotes
Cross-tenant case approval5435critical, regulatory impact
Verbose validation error2452fix but lower priority
Unsigned approval event5234internal boundary but high integrity risk
Secret in debug log5324depends log access and retention
Dependency with unreachable CVE2111triage, not emergency

15. Threat Model to Backlog

Threat model harus menghasilkan backlog yang bisa dieksekusi.

Bad backlog:

Improve security.

Good backlog:

## Story: Enforce tenant-scoped case approval

As a case approval service,
I must deny approval if actor tenant differs from case tenant,
so that cross-tenant approval is impossible even when case UUID is known.

Acceptance Criteria:
- approval policy checks actor tenant against case tenant
- repository query is tenant-scoped where possible
- denial reason CROSS_TENANT is audited
- integration test proves Tenant A reviewer cannot approve Tenant B case
- metric security.authorization.denied increments with reason=CROSS_TENANT

Security backlog yang baik menyebut:

  • invariant,
  • control,
  • test,
  • audit/observability,
  • rollout consideration.

16. Example: End-to-End Threat Model Slice

16.1 Scope

High-risk case approval API.

16.2 Assets

  • case state,
  • approval decision,
  • actor identity,
  • authorization policy,
  • audit event,
  • approval domain event.

16.3 Actors

  • reviewer,
  • case creator,
  • admin,
  • compromised account,
  • internal service,
  • message consumer.

16.4 Trust Boundaries

  • browser to gateway,
  • gateway to Java service,
  • controller to domain,
  • service to database,
  • service to audit store,
  • service to broker,
  • broker to worker.

16.5 Threats and Controls

ThreatInvariantControlValidation
Creator approves own casemaker cannot be checkerdomain policyunit + integration test
Tenant A approves Tenant B caseactor tenant must equal case tenanttenant-scoped load + authzintegration test
Approval event forgedonly signed event acceptedevent signature/MACconsumer negative test
Approval replayedevent id/version must be freshidempotency/replay storereplay test
Audit missingapproval cannot commit without audittransactional outbox/audit policyfailure injection test
Stale token used after disableinactive user cannot approveactive status/policy checktest disabled user

16.6 Derived Java Policy

public final class HighRiskCaseApprovalPolicy {

    public ApprovalDecision evaluate(ActorContext actor, RegulatoryCase caze, Instant now) {
        if (!actor.active()) {
            return ApprovalDecision.deny("ACTOR_INACTIVE");
        }
        if (!actor.tenantId().equals(caze.tenantId())) {
            return ApprovalDecision.deny("CROSS_TENANT");
        }
        if (actor.userId().equals(caze.createdBy())) {
            return ApprovalDecision.deny("MAKER_CHECKER_VIOLATION");
        }
        if (!caze.status().equals(CaseStatus.REVIEWED)) {
            return ApprovalDecision.deny("INVALID_STATE");
        }
        if (!actor.permissions().contains(Permission.APPROVE_HIGH_RISK_CASE)) {
            return ApprovalDecision.deny("MISSING_PERMISSION");
        }
        if (!actor.authStrength().isStrongWithin(now, Duration.ofMinutes(10))) {
            return ApprovalDecision.deny("STEP_UP_AUTH_REQUIRED");
        }
        return ApprovalDecision.allow("HIGH_RISK_APPROVAL_POLICY_V1");
    }
}

16.7 Derived Tests

class HighRiskCaseApprovalPolicyTest {

    private final HighRiskCaseApprovalPolicy policy = new HighRiskCaseApprovalPolicy();
    private final Instant now = Instant.parse("2026-06-30T00:00:00Z");

    @Test
    void deniesCrossTenantApproval() {
        ActorContext actor = Fixtures.reviewer()
                .tenant("tenant-a")
                .permission(Permission.APPROVE_HIGH_RISK_CASE)
                .strongAuthAt(now.minusSeconds(60))
                .build();

        RegulatoryCase caze = Fixtures.highRiskCase()
                .tenant("tenant-b")
                .status(CaseStatus.REVIEWED)
                .createdBy("someone-else")
                .build();

        ApprovalDecision decision = policy.evaluate(actor, caze, now);

        assertThat(decision.allowed()).isFalse();
        assertThat(decision.reasonCode()).isEqualTo("CROSS_TENANT");
    }

    @Test
    void deniesMakerCheckerViolation() {
        ActorContext actor = Fixtures.reviewer()
                .user("user-1")
                .tenant("tenant-a")
                .permission(Permission.APPROVE_HIGH_RISK_CASE)
                .strongAuthAt(now.minusSeconds(60))
                .build();

        RegulatoryCase caze = Fixtures.highRiskCase()
                .tenant("tenant-a")
                .status(CaseStatus.REVIEWED)
                .createdBy("user-1")
                .build();

        ApprovalDecision decision = policy.evaluate(actor, caze, now);

        assertThat(decision.allowed()).isFalse();
        assertThat(decision.reasonCode()).isEqualTo("MAKER_CHECKER_VIOLATION");
    }
}

Tests seperti ini mengubah security dari dokumen menjadi executable invariant.


17. Common Mistakes dalam Threat Modeling

17.1 Mulai dari Technology, Bukan Asset

Salah:

Kita pakai JWT, AES, dan TLS. Jadi threat model-nya apa?

Benar:

Asset apa yang harus dilindungi? Dari actor mana? Pada boundary mana? Dengan invariant apa?

Technology adalah jawaban setelah pertanyaan jelas.

17.2 Menganggap Internal Network Trusted

Internal tidak otomatis trusted. Dalam architecture modern:

  • service account bisa compromised,
  • broker bisa shared,
  • CI runner bisa disalahgunakan,
  • developer laptop bisa bocor,
  • internal admin endpoint bisa diakses melalui SSRF,
  • log system bisa mengekspos secret.

Gunakan prinsip “trusted enough for purpose”, bukan “internal berarti aman”.

17.3 Mengabaikan Background Jobs

Scheduler dan worker sering punya privilege besar dan validasi kecil.

Checklist:

  • Apakah job hanya mengambil data yang boleh diproses?
  • Apakah input job bisa dipengaruhi user?
  • Apakah job idempotent?
  • Apakah job menulis audit?
  • Apakah job memakai service account terlalu luas?
  • Apakah retry bisa menggandakan efek?

17.4 Menganggap Audit Log sebagai Afterthought

Audit harus didesain bersama workflow. Jika audit ditambahkan di akhir, biasanya ia tidak punya context cukup.

Audit event untuk decision harus merekam:

  • actor,
  • resource,
  • action,
  • decision,
  • reason,
  • policy version,
  • state/version,
  • timestamp,
  • correlation id,
  • authentication context,
  • source address/device jika relevan,
  • integrity metadata jika perlu.

17.5 Tidak Menghubungkan Threat ke Test

Threat yang tidak punya validation plan akan terlupakan.

Rule sederhana:

Setiap high-risk threat harus menghasilkan minimal satu negative test, satu review checklist item, atau satu runtime detection.


18. Threat Modeling Checklist untuk Java Review

Gunakan checklist ini saat review desain PR besar.

18.1 Scope

  • Use case sensitif terdefinisi jelas.
  • Entry point dan exit point jelas.
  • External dependency disebut.
  • Out-of-scope ditulis eksplisit.

18.2 Actors

  • Anonymous, authenticated, admin, service account dipisahkan.
  • Compromised legitimate account dipertimbangkan.
  • Partner/external service dipertimbangkan.
  • CI/build actor dipertimbangkan jika terkait release.

18.3 Assets

  • Data asset terdaftar.
  • Action asset terdaftar.
  • Key/secret asset terdaftar.
  • Audit/evidence asset terdaftar.
  • Event/artifact asset terdaftar.

18.4 Boundaries

  • Network boundary ditandai.
  • Identity boundary ditandai.
  • Authorization boundary ditandai.
  • Parser/serialization boundary ditandai.
  • DB transaction boundary ditandai.
  • Message/event boundary ditandai.
  • Build/runtime boundary ditandai bila relevan.

18.5 Threats

  • Spoofing scenario ada.
  • Tampering scenario ada.
  • Repudiation scenario ada.
  • Information disclosure scenario ada.
  • DoS scenario ada.
  • Elevation of privilege scenario ada.
  • Business abuse case ada.

18.6 Controls

  • Control ditempatkan di boundary yang benar.
  • Control punya owner.
  • Control punya test/review/detection.
  • Failure mode control ditentukan.
  • Residual risk dicatat.

19. Practice Drill Part 002

Pilih satu workflow Java yang Anda pahami. Buat threat model slice maksimal 2 halaman.

Template:

# Threat Model Slice: <Workflow>

## Scope
In scope:
Out of scope:

## Actors
| Actor | Capability | Trust Level | Concern |

## Assets
| Asset | Criticality | Security Property |

## Data Flow
<Mermaid sequence or flowchart>

## Trust Boundaries
| ID | Boundary | Assumption Change | Control |

## Threats
| Threat | Actor | Asset | Boundary | Impact | Proposed Invariant |

## Validation
| Invariant | Test/Review/Detection |

## Residual Risk
What remains after controls?

Minimal hasil yang baik:

  • 5 actor,
  • 5 asset,
  • 5 trust boundary,
  • 6 threat,
  • 6 invariant,
  • 6 validation item.

20. Summary

Yang harus dibawa dari Part 002:

  1. Threat modeling adalah alat desain, bukan dokumen formalitas.
  2. Asset mencakup data, action, key, audit, event, artifact, dan runtime capability.
  3. Actor mencakup manusia, service, job, CI runner, dependency, dan compromised legitimate actor.
  4. Trust boundary adalah titik perubahan asumsi, bukan hanya network line.
  5. Threat yang baik memiliki actor, capability, path, asset, dan impact.
  6. Threat harus berubah menjadi invariant, control, dan validation.
  7. Dalam Java enterprise, hidden boundary sering muncul pada token claim, repository query, event consumer, file parser, dan DTO-to-domain conversion.
  8. High-risk threat tanpa test atau detection adalah risk yang belum benar-benar dikelola.

Part berikutnya akan masuk ke Java Security Architecture in Modern JDK: package, provider model, JCA/JCE/JSSE, keystore/truststore, dan konsekuensi desain setelah Security Manager tidak lagi menjadi boundary security modern.

Lesson Recap

You just completed lesson 02 in start here. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.