From 82a277f7ecb91e228106ef4bb76b77192977ad94 Mon Sep 17 00:00:00 2001 From: arun Date: Wed, 15 Jul 2026 17:13:42 +0100 Subject: [PATCH 01/18] HDPI-7052: Pin Jenkins library to Infrastructure@2.4.5 --- Jenkinsfile_CNP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile_CNP b/Jenkinsfile_CNP index 9692d77ba7..a216e91034 100644 --- a/Jenkinsfile_CNP +++ b/Jenkinsfile_CNP @@ -1,6 +1,6 @@ #!groovy -@Library("Infrastructure") +@Library("Infrastructure@2.4.5") import uk.gov.hmcts.contino.AppPipelineDsl import uk.gov.hmcts.contino.GithubAPI From c89ea7d75aaf2387c2fc1d995e2f7ea5d39301a4 Mon Sep 17 00:00:00 2001 From: arun Date: Wed, 15 Jul 2026 14:34:32 +0100 Subject: [PATCH 02/18] HDPI-7052: preview chart - ORM env, PRM scheduling, group access filtering --- charts/pcs-api/Chart.yaml | 2 +- charts/pcs-api/values.ccd.preview.template.yaml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/charts/pcs-api/Chart.yaml b/charts/pcs-api/Chart.yaml index 59c41dd79e..3e400710d6 100644 --- a/charts/pcs-api/Chart.yaml +++ b/charts/pcs-api/Chart.yaml @@ -3,7 +3,7 @@ appVersion: "1.0" description: A Helm chart for pcs-api App name: pcs-api home: https://github.com/hmcts/pcs-api -version: 0.0.66 +version: 0.0.67 maintainers: - name: HMCTS pcs team dependencies: diff --git a/charts/pcs-api/values.ccd.preview.template.yaml b/charts/pcs-api/values.ccd.preview.template.yaml index 275d3b704c..f5a00a4d36 100644 --- a/charts/pcs-api/values.ccd.preview.template.yaml +++ b/charts/pcs-api/values.ccd.preview.template.yaml @@ -113,6 +113,7 @@ ccd: ELASTIC_SEARCH_HOSTS: "http://{{ .Release.Name }}-es-master:9200" CCD_S2S_AUTHORISED_SERVICES_CASE_USER_ROLES: "aac_manage_case_assignment,pcs_api,pcs_frontend" CASE_DOCUMENT_AM_URL: http://${SERVICE_NAME}-cdam + ENABLE_CASE_GROUP_ACCESS_FILTERING: true ingressHost: ccd-data-store-api-${SERVICE_FQDN} autoscaling: enabled: false @@ -342,6 +343,9 @@ am-org-role-mapping-service: REFRESH_BULK_ASSIGNMENT_INCLUDE_BOOKINGS: true DB_FEATURE_FLAG_ENABLE: st_cic_wa_1_0 ORM_ENV: pr + CCD_DEF_STORE_APP_URL: http://${SERVICE_NAME}-ccd-definition-store + PROFESSIONAL_REF_APP_URL: http://rd-professional-api-aat.service.core-compute-aat.internal + PROFESSIONAL_SCHEDULING_ENABLED: true aac-manage-case-assignment: enabled: true From c50276b275bbd0a7b5ee79946fb7ef5353742f3f Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 12:08:29 +0100 Subject: [PATCH 03/18] HDPI-7052: pin Jenkins library to existing tag 2.4.4 --- Jenkinsfile_CNP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile_CNP b/Jenkinsfile_CNP index a216e91034..f3d8865800 100644 --- a/Jenkinsfile_CNP +++ b/Jenkinsfile_CNP @@ -1,6 +1,6 @@ #!groovy -@Library("Infrastructure@2.4.5") +@Library("Infrastructure@2.4.4") import uk.gov.hmcts.contino.AppPipelineDsl import uk.gov.hmcts.contino.GithubAPI From 9405562d3e77aea9eceacefb29a42ac4d5748147 Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 12:30:01 +0100 Subject: [PATCH 04/18] HDPI-7052: align group access config to agreed RRFM values --- .../uk/gov/hmcts/reform/pcs/ccd/CaseType.java | 57 +++++++++++++------ .../pcs/ccd/accesscontrol/AccessProfile.java | 2 + .../pcs/ccd/accesscontrol/UserRole.java | 4 +- .../pcs/ccd/config/HighLevelDataSetupApp.java | 2 +- 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index 604ec221bc..a9a386529a 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -12,9 +12,11 @@ import java.util.Arrays; import java.util.EnumSet; +import java.util.List; import static java.lang.System.getenv; import static java.util.Optional.ofNullable; +import static uk.gov.hmcts.ccd.sdk.api.Permission.CRU; import static uk.gov.hmcts.reform.pcs.ccd.ShowConditions.NEVER_SHOW; import static uk.gov.hmcts.reform.pcs.ccd.domain.State.AWAITING_SUBMISSION_TO_HMCTS; @@ -121,30 +123,53 @@ public void configure(final ConfigBuilder builder .accessMandatory(true) .accessDefault(true) .display(false) + .description("Access to create cases") .hintText("Access to create cases") .displayOrder(1) .liveTo("01/01/2027"); - builder.accessType("prof-org-access") - .organisationProfileId("LOCALAUTH_PROFILE") - .accessMandatory(false) - .accessDefault(false) - .display(true) - .description("Can manage all cases associated with this organisation") - .hintText("Assign to Users to enable access to all cases associated with this organisation") - .displayOrder(2) - .liveTo("01/01/2027"); builder.accessTypeRole("create-cases") .organisationProfileId("LOCALAUTH_PROFILE") .organisationalRoleName(UserRole.SOLICITOR.getRole()) .liveTo("01/01/2027"); - builder.accessTypeRole("prof-org-access") - .organisationProfileId("LOCALAUTH_PROFILE") - .groupRoleName(UserRole.SOLICITOR.getRole()) - .caseAssignedRoleField(UserRole.PROFESSIONA_USER.getRole()) - .groupAccessEnabled(true) - .caseAccessGroupIdTemplate("PCS:PCS:prof-org-access:solicitor:$ORGID$") - .liveTo("01/01/2027"); + + // Org profiles per the agreed RRFM Group Access config (page 1973313166) + List groupAccessOrgProfiles = List.of( + "SOLICITOR_PROFILE", + "LOCALAUTH_PROFILE", + "OTHER_REALT_PROFILE", + "OTHER_PROP_PROFILE", + "OTHER_NFP_PROFILE", + "OTHER_CHARITY_PROFILE" + ); + + for (String orgProfile : groupAccessOrgProfiles) { + builder.accessType("prof-org-access") + .organisationProfileId(orgProfile) + .accessMandatory(false) + .accessDefault(false) + .display(true) + .description("Can manage all cases associated with this organisation") + .hintText("Assign to Users to enable access to all cases associated with this organisation") + .displayOrder(2) + .liveTo("01/01/2027"); + + // GroupAccessEnabled is No in the agreed config until case migration is settled; + // Yes here so the group role can be exercised on test environments. + builder.accessTypeRole("prof-org-access") + .organisationProfileId(orgProfile) + .groupRoleName(UserRole.SOLICITOR.getRole()) + .caseAssignedRoleField(UserRole.PROFESSIONAL_USER.getRole()) + .groupAccessEnabled(true) + .caseAccessGroupIdTemplate("pcs:pcs:prof-org-access:solicitor:$ORGID$") + .liveTo("01/01/2027"); + } + + // State-level access for the group-access profiles; without these the data store + // filters matched cases out regardless of the caseAccessGroupId key. + for (State state : State.values()) { + builder.grant(state, CRU, AccessProfile.SOLICITOR, AccessProfile.PROFESSIONAL_USER); + } buildCaseListView(builder); diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java index 3938f5b9fc..eb3701d0ca 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java @@ -21,6 +21,8 @@ public enum AccessProfile implements HasRole { DEFENDANT_SOLICITOR("[DEFENDANTSOLICITOR]", CRU), PCS_CASE_WORKER("caseworker-pcs", Set.of(R)), PCS_SOLICITOR("caseworker-pcs-solicitor", CRU), + SOLICITOR("solicitor", CRU), + PROFESSIONAL_USER("professional-user", CRU), JUDGE("judge", Set.of(R)), FEE_PAID_JUDGE("fee-paid-judge", Set.of(R)), diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java index 107ec3a477..89c8c29215 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java @@ -23,8 +23,8 @@ public enum UserRole implements HasRole { RAS_VALIDATOR("caseworker-ras-validation", Set.of(R), IDAM), CITIZEN("citizen", CRU, IDAM), - SOLICITOR("[SOLICITOR]", CRU, RAS), - PROFESSIONA_USER("professional-user", CRU, RAS), + SOLICITOR("solicitor", CRU, RAS), + PROFESSIONAL_USER("professional-user", CRU, RAS), DEFENDANT("[DEFENDANT]", CRU, RAS), CLAIMANT_SOLICITOR("[CLAIMANTSOLICITOR]", CRU, RAS), DEFENDANT_SOLICITOR("[DEFENDANTSOLICITOR]", CRU, RAS), diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java index aaf9d4df3e..f5ae672a88 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java @@ -37,7 +37,7 @@ public class HighLevelDataSetupApp extends DataLoaderToDefinitionStore { new CcdRoleConfig("circuit-judge", "PUBLIC"), new CcdRoleConfig("leadership-judge", "PUBLIC"), new CcdRoleConfig("pcs-system-update", "PUBLIC"), - new CcdRoleConfig("[SOLICITOR]", "PUBLIC"), + new CcdRoleConfig("solicitor", "PUBLIC"), new CcdRoleConfig("professional-user", "PUBLIC") }; From 93fa3b7de37f8852d4ace73619b312b84f508ed5 Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 12:30:47 +0100 Subject: [PATCH 05/18] HDPI-7052: LOCALAUTH profile first while SDK keeps one row per access type --- src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index a9a386529a..f0b1ccfe39 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -133,10 +133,12 @@ public void configure(final ConfigBuilder builder .organisationalRoleName(UserRole.SOLICITOR.getRole()) .liveTo("01/01/2027"); - // Org profiles per the agreed RRFM Group Access config (page 1973313166) + // Org profiles per the agreed RRFM Group Access config (page 1973313166). + // The SDK currently keeps only the FIRST row per AccessTypeID, so LOCALAUTH + // (the profile of the test organisations) must lead until that is fixed. List groupAccessOrgProfiles = List.of( - "SOLICITOR_PROFILE", "LOCALAUTH_PROFILE", + "SOLICITOR_PROFILE", "OTHER_REALT_PROFILE", "OTHER_PROP_PROFILE", "OTHER_NFP_PROFILE", From c650d94a8857165fc736a8d23fc3ff7bdff3aa87 Mon Sep 17 00:00:00 2001 From: scottstewart-sl <202802468+scottstewart-sl@users.noreply.github.com> Date: Fri, 17 Jul 2026 10:35:53 +0100 Subject: [PATCH 06/18] HDPI-7052: switch sonar project key to pcs-api-2 (#2199) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a60309ec95..a4a9dab139 100644 --- a/build.gradle +++ b/build.gradle @@ -322,7 +322,7 @@ tasks.named('check') { sonarqube { properties { property "sonar.projectName", "Reform :: pcs-api" - property "sonar.projectKey", "uk.gov.hmcts.reform:pcs-api" + property "sonar.projectKey", "uk.gov.hmcts.reform:pcs-api-2" property "sonar.exclusions", ".github/workflows/publish-openapi.yaml" property "sonar.coverage.exclusions", "**/config/**/*Configuration.java," + "**/*Constants.java," + From 89bd56832debcafee7c4d4df33f15af9d09f66f9 Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 13:51:26 +0100 Subject: [PATCH 07/18] HDPI-7052: uppercase group template - def store requires service name prefix --- src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index f0b1ccfe39..b0d9f272ca 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -163,7 +163,9 @@ public void configure(final ConfigBuilder builder .groupRoleName(UserRole.SOLICITOR.getRole()) .caseAssignedRoleField(UserRole.PROFESSIONAL_USER.getRole()) .groupAccessEnabled(true) - .caseAccessGroupIdTemplate("pcs:pcs:prof-org-access:solicitor:$ORGID$") + // Must start with the service name in upper case: the definition store rejects + // the lowercase template on the agreed RRFM page ("must start with 'PCS'"). + .caseAccessGroupIdTemplate("PCS:PCS:prof-org-access:solicitor:$ORGID$") .liveTo("01/01/2027"); } From 890177091db64471e4a5c132df3a5add24b39ffd Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 14:07:54 +0100 Subject: [PATCH 08/18] HDPI-7052: trim config comment --- src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index b0d9f272ca..8b8e97af5b 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -133,9 +133,8 @@ public void configure(final ConfigBuilder builder .organisationalRoleName(UserRole.SOLICITOR.getRole()) .liveTo("01/01/2027"); - // Org profiles per the agreed RRFM Group Access config (page 1973313166). - // The SDK currently keeps only the FIRST row per AccessTypeID, so LOCALAUTH - // (the profile of the test organisations) must lead until that is fixed. + // Org profiles per the agreed RRFM Group Access config. The SDK keeps only the + // first row per AccessTypeID, so LOCALAUTH (the test orgs' profile) must lead. List groupAccessOrgProfiles = List.of( "LOCALAUTH_PROFILE", "SOLICITOR_PROFILE", From 53ba9be637cb8c7aae2317e567ae63ae8af384a0 Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 16:26:13 +0100 Subject: [PATCH 09/18] HDPI-7052: enable ORM professional refresh API on preview --- charts/pcs-api/Chart.yaml | 2 +- charts/pcs-api/values.ccd.preview.template.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/charts/pcs-api/Chart.yaml b/charts/pcs-api/Chart.yaml index 3e400710d6..5dfd6abf84 100644 --- a/charts/pcs-api/Chart.yaml +++ b/charts/pcs-api/Chart.yaml @@ -3,7 +3,7 @@ appVersion: "1.0" description: A Helm chart for pcs-api App name: pcs-api home: https://github.com/hmcts/pcs-api -version: 0.0.67 +version: 0.0.68 maintainers: - name: HMCTS pcs team dependencies: diff --git a/charts/pcs-api/values.ccd.preview.template.yaml b/charts/pcs-api/values.ccd.preview.template.yaml index f5a00a4d36..15c4e4ca55 100644 --- a/charts/pcs-api/values.ccd.preview.template.yaml +++ b/charts/pcs-api/values.ccd.preview.template.yaml @@ -346,6 +346,7 @@ am-org-role-mapping-service: CCD_DEF_STORE_APP_URL: http://${SERVICE_NAME}-ccd-definition-store PROFESSIONAL_REF_APP_URL: http://rd-professional-api-aat.service.core-compute-aat.internal PROFESSIONAL_SCHEDULING_ENABLED: true + PROFESSIONAL_REFRESH_API_ENABLED: true aac-manage-case-assignment: enabled: true From 4046c90cca02d14f527104319d5f4e29f848f0bc Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 17 Jul 2026 17:04:03 +0100 Subject: [PATCH 10/18] HDPI-7052: restore ACR login on Jenkins agents in create-xlsx.sh --- bin/create-xlsx.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/create-xlsx.sh b/bin/create-xlsx.sh index 7f9de97d56..af19ed2e7a 100755 --- a/bin/create-xlsx.sh +++ b/bin/create-xlsx.sh @@ -8,8 +8,10 @@ if [ -z "$env" ]; then echo "No environment specified, defaulting to the local naming convention." fi -# Authenticate with Azure Container Registry -#env AZURE_CONFIG_DIR=/opt/jenkins/.azure-nonprod az acr login --name hmctsprod --subscription DCD-CNP-PROD +# Authenticate with Azure Container Registry (Jenkins agents only; skipped locally) +if [ -d /opt/jenkins/.azure-nonprod ]; then + env AZURE_CONFIG_DIR=/opt/jenkins/.azure-nonprod az acr login --name hmctsprod --subscription DCD-CNP-PROD +fi for case_dir in "$run_dir"/build/definitions/*/; do case_type=$(basename "$case_dir") From 9e6581f83b5be52744c6905e401eed2c62619bb2 Mon Sep 17 00:00:00 2001 From: arun Date: Mon, 20 Jul 2026 21:09:47 +0100 Subject: [PATCH 11/18] HDPI-7052: use [SOLICITOR] group role with SDK bracket-ACL fix (99.1-ee757057) --- build.gradle | 2 +- .../gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java | 2 +- .../uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java | 2 +- .../gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index a4a9dab139..35f0eb3283 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ plugins { id 'org.flywaydb.flyway' version "$flywayVersion" id 'org.sonarqube' version '7.3.1.8318' id 'net.serenity-bdd.serenity-gradle-plugin' version "$serenityBddVersion" - id 'hmcts.ccd.sdk' version 'HDPI-6258-generate-accessType-accessTypeRole-json-74.1-20933aed' + id 'hmcts.ccd.sdk' version 'HDPI-6258-generate-accessType-accessTypeRole-json-99.1-ee757057' id 'com.github.hmcts.rse-cft-lib' version '0.19.2220' id 'io.freefair.lombok' version '9.5.0' id 'au.com.dius.pact' version '4.7.3' diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java index eb3701d0ca..0ab826983d 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/AccessProfile.java @@ -21,7 +21,7 @@ public enum AccessProfile implements HasRole { DEFENDANT_SOLICITOR("[DEFENDANTSOLICITOR]", CRU), PCS_CASE_WORKER("caseworker-pcs", Set.of(R)), PCS_SOLICITOR("caseworker-pcs-solicitor", CRU), - SOLICITOR("solicitor", CRU), + SOLICITOR("[SOLICITOR]", CRU), PROFESSIONAL_USER("professional-user", CRU), JUDGE("judge", Set.of(R)), diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java index 89c8c29215..b18b7fc0a0 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/accesscontrol/UserRole.java @@ -23,7 +23,7 @@ public enum UserRole implements HasRole { RAS_VALIDATOR("caseworker-ras-validation", Set.of(R), IDAM), CITIZEN("citizen", CRU, IDAM), - SOLICITOR("solicitor", CRU, RAS), + SOLICITOR("[SOLICITOR]", CRU, RAS), PROFESSIONAL_USER("professional-user", CRU, RAS), DEFENDANT("[DEFENDANT]", CRU, RAS), CLAIMANT_SOLICITOR("[CLAIMANTSOLICITOR]", CRU, RAS), diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java index f5ae672a88..aaf9d4df3e 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/config/HighLevelDataSetupApp.java @@ -37,7 +37,7 @@ public class HighLevelDataSetupApp extends DataLoaderToDefinitionStore { new CcdRoleConfig("circuit-judge", "PUBLIC"), new CcdRoleConfig("leadership-judge", "PUBLIC"), new CcdRoleConfig("pcs-system-update", "PUBLIC"), - new CcdRoleConfig("solicitor", "PUBLIC"), + new CcdRoleConfig("[SOLICITOR]", "PUBLIC"), new CcdRoleConfig("professional-user", "PUBLIC") }; From d25c91f8a89872ee951e3682f649ef8d2774aa27 Mon Sep 17 00:00:00 2001 From: arun Date: Tue, 21 Jul 2026 07:17:18 +0100 Subject: [PATCH 12/18] HDPI-7052: stamp cases with group access key (WK8GIHE interim) + serialization fix --- .../gov/hmcts/reform/pcs/ccd/PCSCaseView.java | 24 +++++++++++++++++++ .../pcs/ccd/domain/GroupAccessFields.java | 5 +++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java index bef0cb04eb..aafb8ca0c4 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java @@ -149,6 +149,7 @@ private SubmittedCase getSubmittedCase(long caseReference) { .build(); setDerivedProperties(pcsCase, pcsCaseEntity); + setGroupAccessFields(pcsCase); partiesView.setCaseFields(pcsCase, pcsCaseEntity); claimView.setCaseFields(pcsCase, pcsCaseEntity); @@ -196,6 +197,29 @@ private LocalDate getClaimIssueDateLocal(PcsCaseEntity pcsCaseEntity) { .orElse(null); } + // INTERIM: stamp the case with the group-access key so the data store's caseAccessGroupId + // matcher can grant org-wide access. Hardcoded to the WK8GIHE test org for the preview demo. + // TODO derive from the case creator's organisation (PRD lookup, persisted at create time), + // and delete once the decentralised runtime stamps CaseAccessGroups itself. + private void setGroupAccessFields(PCSCase pcsCase) { + uk.gov.hmcts.ccd.sdk.type.CaseAccessGroup caseAccessGroup = + uk.gov.hmcts.ccd.sdk.type.CaseAccessGroup.builder() + .caseAccessGroupId("PCS:PCS:prof-org-access:solicitor:WK8GIHE") + .caseAccessGroupType("CCD:all-cases-access") + .build(); + + ListValue wrapped = + ListValue.builder() + .id(UUID.nameUUIDFromBytes(caseAccessGroup.getCaseAccessGroupId().getBytes()).toString()) + .value(caseAccessGroup) + .build(); + + uk.gov.hmcts.reform.pcs.ccd.domain.GroupAccessFields + groupAccessFields = new uk.gov.hmcts.reform.pcs.ccd.domain.GroupAccessFields<>(); + groupAccessFields.setCaseAccessGroups(List.of(wrapped)); + pcsCase.setGroupAccessFields(groupAccessFields); + } + private void setDerivedProperties(PCSCase pcsCase, PcsCaseEntity pcsCaseEntity) { boolean pcqIdSet = findPartyForCurrentUser(pcsCaseEntity) .map(party -> party.getPcqId() != null) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/GroupAccessFields.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/GroupAccessFields.java index 4094c350f5..0d5ebc5639 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/GroupAccessFields.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/domain/GroupAccessFields.java @@ -2,19 +2,22 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; +import lombok.Data; import uk.gov.hmcts.ccd.sdk.api.CCD; import uk.gov.hmcts.ccd.sdk.api.HasRole; import uk.gov.hmcts.ccd.sdk.type.CaseAccessGroup; import uk.gov.hmcts.ccd.sdk.type.ChangeOrganisationRequest; +import uk.gov.hmcts.ccd.sdk.type.ListValue; import uk.gov.hmcts.ccd.sdk.type.Organisation; import uk.gov.hmcts.ccd.sdk.type.OrganisationPolicy; import uk.gov.hmcts.reform.pcs.ccd.accesscontrol.AccessProfile; +@Data public class GroupAccessFields { @JsonProperty("CaseAccessGroups") @CCD - private List caseAccessGroups; + private List> caseAccessGroups; @JsonProperty("OrganisationField") @CCD From dc53d1bd39cd01a433d36963f71046043c84d88e Mon Sep 17 00:00:00 2001 From: arun Date: Tue, 21 Jul 2026 08:23:52 +0100 Subject: [PATCH 13/18] HDPI-7052: repoint def-processor image to live PR-348 tag (64dd53f purged) --- bin/create-xlsx.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/create-xlsx.sh b/bin/create-xlsx.sh index af19ed2e7a..ff0fad9549 100755 --- a/bin/create-xlsx.sh +++ b/bin/create-xlsx.sh @@ -28,7 +28,7 @@ for case_dir in "$run_dir"/build/definitions/*/; do docker run --rm --name "json2xlsx" \ -v "$run_dir/build/definitions/${case_type}:/tmp/ccd-input" \ -v "$run_dir/build/definitions:/tmp/ccd-output" \ - hmctsprod.azurecr.io/ccd/definition-processor:pr-348-64dd53f \ + hmctsprod.azurecr.io/ccd/definition-processor:pr-348-7561002 \ json2xlsx -D /tmp/ccd-input -o /tmp/ccd-output/"${ccd_definition_file}" done From f6d0c93706600e5ab8bddaab18465332f2dfd144 Mon Sep 17 00:00:00 2001 From: arun Date: Thu, 23 Jul 2026 14:00:31 +0100 Subject: [PATCH 14/18] HDPI-7052: suppress ES rest-client 8.18.8 CVEs (transitive, cftlib-only) --- config/owasp/suppressions.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/owasp/suppressions.xml b/config/owasp/suppressions.xml index bac56b8542..c2f8fd7718 100644 --- a/config/owasp/suppressions.xml +++ b/config/owasp/suppressions.xml @@ -30,5 +30,11 @@ CVE-2025-7962 + + + CVE-2025-37731 + CVE-2025-68384 + CVE-2025-68390 + From 6cb97c723dd4bf15b818f97919bd5fb047cd6cfa Mon Sep 17 00:00:00 2001 From: arun Date: Thu, 23 Jul 2026 14:36:46 +0100 Subject: [PATCH 15/18] HDPI-7052: stub accessType in CaseTypeTest so shutter tests pass --- src/test/java/uk/gov/hmcts/reform/pcs/ccd/CaseTypeTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/CaseTypeTest.java b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/CaseTypeTest.java index c2a0cdf347..7bef9c4009 100644 --- a/src/test/java/uk/gov/hmcts/reform/pcs/ccd/CaseTypeTest.java +++ b/src/test/java/uk/gov/hmcts/reform/pcs/ccd/CaseTypeTest.java @@ -201,6 +201,10 @@ private void stubBuilderForConfigure() { when(builder.searchCasesFields()).thenReturn(searchCasesBuilder); when(builder.searchResultFields()).thenReturn(searchBuilder); when(builder.workBasketResultFields()).thenReturn(searchBuilder); + when(builder.accessType(anyString())) + .thenReturn(AccessType.AccessTypeBuilder.builder("accessTypeId")); + when(builder.accessTypeRole(anyString())) + .thenReturn(AccessTypeRole.AccessTypeRoleBuilder.builder("accessTypeId")); when(builder.tab("nextSteps", "Next steps")).thenReturn(TabBuilder.builder(PCSCase.class, utils)); when(builder.tab("summary", "Summary")).thenReturn(TabBuilder.builder(PCSCase.class, utils)); when(builder.tab("CaseHistory", "History")).thenReturn(TabBuilder.builder(PCSCase.class, utils)); From 82a3635415264bb1f2991e544a9fc95dd1e93695 Mon Sep 17 00:00:00 2001 From: arun Date: Thu, 23 Jul 2026 18:25:53 +0100 Subject: [PATCH 16/18] HDPI-7052: preview uses shared AAT RAS/ORM, drop per-PR AM services --- charts/pcs-api/Chart.yaml | 2 +- charts/pcs-api/values.ccd.preview.template.yaml | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/charts/pcs-api/Chart.yaml b/charts/pcs-api/Chart.yaml index 033b9600dd..5f2bba1a0c 100644 --- a/charts/pcs-api/Chart.yaml +++ b/charts/pcs-api/Chart.yaml @@ -3,7 +3,7 @@ appVersion: "1.0" description: A Helm chart for pcs-api App name: pcs-api home: https://github.com/hmcts/pcs-api -version: 0.0.77 +version: 0.0.78 maintainers: - name: HMCTS pcs team dependencies: diff --git a/charts/pcs-api/values.ccd.preview.template.yaml b/charts/pcs-api/values.ccd.preview.template.yaml index 15c4e4ca55..7b0fc14b20 100644 --- a/charts/pcs-api/values.ccd.preview.template.yaml +++ b/charts/pcs-api/values.ccd.preview.template.yaml @@ -60,7 +60,7 @@ ccd: apiGatewayWeb: enabled: true ras: - enabled: true + enabled: false elastic: enabled: true ccd-definition-store-api: @@ -230,8 +230,8 @@ xui-webapp: SERVICES_CCD_COMPONENT_API: http://${SERVICE_NAME}-ccd-api-gw SERVICES_CCD_DATA_STORE_API: http://${SERVICE_NAME}-ccd-data-store-api SERVICES_CCD_CASE_ASSIGNMENT_API: http://${SERVICE_NAME}-aac-manage-case-assignment - SERVICES_ROLE_ASSIGNMENT_API: http://${SERVICE_NAME}-am-role-assignment-service - SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://${SERVICE_NAME}-am-org-role-mapping-service + SERVICES_ROLE_ASSIGNMENT_API: http://am-role-assignment-service-aat.service.core-compute-aat.internal + SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://am-org-role-mapping-service-aat.service.core-compute-aat.internal SERVICES_TERMS_AND_CONDITIONS: http://xui-terms-and-conditions-aat.service.core-compute-aat.internal SERVICES_HEARINGS_COMPONENT_API: http://jurisdiction-hearings-api-aat.service.core-compute-aat.internal JURISDICTIONS: PCS @@ -278,8 +278,8 @@ xui-mo-webapp: CASE_TYPES: PCS FEATURE_OGD_UPDATE_REFRESH_USER_ENABLED: true SERVICES_CCD_CASE_ASSIGNMENT_API: http://${SERVICE_NAME}-aac-manage-case-assignment - SERVICES_ROLE_ASSIGNMENT_API: http://${SERVICE_NAME}-am-role-assignment-service - SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://${SERVICE_NAME}-am-org-role-mapping-service + SERVICES_ROLE_ASSIGNMENT_API: http://am-role-assignment-service-aat.service.core-compute-aat.internal + SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://am-org-role-mapping-service-aat.service.core-compute-aat.internal SERVICES_CCD_DEFINITION_STORE_API: http://${SERVICE_NAME}-ccd-definition-store ccd-case-document-am-api: @@ -304,7 +304,7 @@ ccd-case-document-am-api: alias: CASE_DOCUMENT_AM_API_S2S_SECRET am-org-role-mapping-service: - enabled: true + enabled: false java: image: 'hmctsprod.azurecr.io/am/org-role-mapping-service:latest' ingressHost: am-org-role-mapping-service-${SERVICE_FQDN} @@ -369,7 +369,7 @@ aac-manage-case-assignment: PRD_HOST: http://rd-professional-api-aat.service.core-compute-aat.internal CCD_DEFINITION_STORE_ALLOWED_SERVICE: xui_webapp CCD_DATA_STORE_ALLOWED_SERVICE: xui_webapp - ROLE_ASSIGNMENT_URL: http://${SERVICE_NAME}-am-role-assignment-service + ROLE_ASSIGNMENT_URL: http://am-role-assignment-service-aat.service.core-compute-aat.internal autoscaling: enabled: false keyVaults: From 8b80ce83f0964f5be8c519b245ba3c5acbee049c Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 24 Jul 2026 09:04:32 +0100 Subject: [PATCH 17/18] HDPI-7052: self-contained preview - per-PR RAS/ORM, refresh script --- charts/pcs-api/Chart.yaml | 2 +- .../pcs-api/values.ccd.preview.template.yaml | 14 +++---- docs/group-access/refresh.sh | 40 +++++++++++++++++++ 3 files changed, 48 insertions(+), 8 deletions(-) create mode 100755 docs/group-access/refresh.sh diff --git a/charts/pcs-api/Chart.yaml b/charts/pcs-api/Chart.yaml index 5f2bba1a0c..42a9d67769 100644 --- a/charts/pcs-api/Chart.yaml +++ b/charts/pcs-api/Chart.yaml @@ -3,7 +3,7 @@ appVersion: "1.0" description: A Helm chart for pcs-api App name: pcs-api home: https://github.com/hmcts/pcs-api -version: 0.0.78 +version: 0.0.79 maintainers: - name: HMCTS pcs team dependencies: diff --git a/charts/pcs-api/values.ccd.preview.template.yaml b/charts/pcs-api/values.ccd.preview.template.yaml index 7b0fc14b20..15c4e4ca55 100644 --- a/charts/pcs-api/values.ccd.preview.template.yaml +++ b/charts/pcs-api/values.ccd.preview.template.yaml @@ -60,7 +60,7 @@ ccd: apiGatewayWeb: enabled: true ras: - enabled: false + enabled: true elastic: enabled: true ccd-definition-store-api: @@ -230,8 +230,8 @@ xui-webapp: SERVICES_CCD_COMPONENT_API: http://${SERVICE_NAME}-ccd-api-gw SERVICES_CCD_DATA_STORE_API: http://${SERVICE_NAME}-ccd-data-store-api SERVICES_CCD_CASE_ASSIGNMENT_API: http://${SERVICE_NAME}-aac-manage-case-assignment - SERVICES_ROLE_ASSIGNMENT_API: http://am-role-assignment-service-aat.service.core-compute-aat.internal - SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://am-org-role-mapping-service-aat.service.core-compute-aat.internal + SERVICES_ROLE_ASSIGNMENT_API: http://${SERVICE_NAME}-am-role-assignment-service + SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://${SERVICE_NAME}-am-org-role-mapping-service SERVICES_TERMS_AND_CONDITIONS: http://xui-terms-and-conditions-aat.service.core-compute-aat.internal SERVICES_HEARINGS_COMPONENT_API: http://jurisdiction-hearings-api-aat.service.core-compute-aat.internal JURISDICTIONS: PCS @@ -278,8 +278,8 @@ xui-mo-webapp: CASE_TYPES: PCS FEATURE_OGD_UPDATE_REFRESH_USER_ENABLED: true SERVICES_CCD_CASE_ASSIGNMENT_API: http://${SERVICE_NAME}-aac-manage-case-assignment - SERVICES_ROLE_ASSIGNMENT_API: http://am-role-assignment-service-aat.service.core-compute-aat.internal - SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://am-org-role-mapping-service-aat.service.core-compute-aat.internal + SERVICES_ROLE_ASSIGNMENT_API: http://${SERVICE_NAME}-am-role-assignment-service + SERVICES_ROLE_ASSIGNMENT_MAPPING_API: http://${SERVICE_NAME}-am-org-role-mapping-service SERVICES_CCD_DEFINITION_STORE_API: http://${SERVICE_NAME}-ccd-definition-store ccd-case-document-am-api: @@ -304,7 +304,7 @@ ccd-case-document-am-api: alias: CASE_DOCUMENT_AM_API_S2S_SECRET am-org-role-mapping-service: - enabled: false + enabled: true java: image: 'hmctsprod.azurecr.io/am/org-role-mapping-service:latest' ingressHost: am-org-role-mapping-service-${SERVICE_FQDN} @@ -369,7 +369,7 @@ aac-manage-case-assignment: PRD_HOST: http://rd-professional-api-aat.service.core-compute-aat.internal CCD_DEFINITION_STORE_ALLOWED_SERVICE: xui_webapp CCD_DATA_STORE_ALLOWED_SERVICE: xui_webapp - ROLE_ASSIGNMENT_URL: http://am-role-assignment-service-aat.service.core-compute-aat.internal + ROLE_ASSIGNMENT_URL: http://${SERVICE_NAME}-am-role-assignment-service autoscaling: enabled: false keyVaults: diff --git a/docs/group-access/refresh.sh b/docs/group-access/refresh.sh new file mode 100755 index 0000000000..4417ef197f --- /dev/null +++ b/docs/group-access/refresh.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Trigger PRM refresh for a professional user on a PCS PR preview, then show RAS result. +# Requires HMCTS VPN (the S2S lease URL is internal). jq required. +# +# export IDAM_CLIENT_SECRET= # from the Postman env or pcs-aat vault +# ./refresh.sh [pr-number] +# ./refresh.sh 3b18bab9-33a3-420f-b37e-b63e73862828 2179 # johnwoo on pr-2179 +set -euo pipefail + +USER_ID="${1:?usage: refresh.sh [pr-number]}" +PR="${2:-2179}" +CLIENT_SECRET="${IDAM_CLIENT_SECRET:?export IDAM_CLIENT_SECRET (pcs-frontend) first}" +IDAM_USER="${IDAM_USER:-johnwoo@johnwoo.com}" +IDAM_PASS="${IDAM_PASS:-Testing12345}" + +IDAM=https://idam-api.aat.platform.hmcts.net +S2S=http://rpe-service-auth-provider-aat.service.core-compute-aat.internal +ORM=https://am-org-role-mapping-service-pcs-api-pr-${PR}.preview.platform.hmcts.net +RAS=https://am-role-assignment-service-pcs-api-pr-${PR}.preview.platform.hmcts.net + +echo "== auth ==" +TOKEN=$(curl -s -X POST "$IDAM/o/token" \ + -d grant_type=password -d "username=$IDAM_USER" -d "password=$IDAM_PASS" \ + -d client_id=pcs-frontend -d "client_secret=$CLIENT_SECRET" -d 'scope=openid profile roles' \ + | jq -r .access_token) +[ -n "$TOKEN" ] && [ "$TOKEN" != null ] || { echo "IDAM login failed"; exit 1; } +S2S_ORM=$(curl -s -X POST "$S2S/testing-support/lease" -H 'Content-Type: application/json' -d '{"microservice":"am_org_role_mapping_service"}') +S2S_CCD=$(curl -s -X POST "$S2S/testing-support/lease" -H 'Content-Type: application/json' -d '{"microservice":"ccd_data"}') +echo " ok (idam ${#TOKEN}, s2sOrm ${#S2S_ORM}, s2sCcd ${#S2S_CCD})" + +echo "== PRM refresh $USER_ID ==" +curl -s -o /dev/null -w ' -> HTTP %{http_code}\n' -X POST \ + "$ORM/am/role-mapping/professional/refresh?userId=$USER_ID" \ + -H "Authorization: Bearer $TOKEN" -H "ServiceAuthorization: Bearer $S2S_ORM" + +sleep 5 +echo "== RAS assignments for $USER_ID ==" +curl -s "$RAS/am/role-assignments/actors/$USER_ID" \ + -H "Authorization: Bearer $TOKEN" -H "ServiceAuthorization: Bearer $S2S_CCD" | jq . +# 422 on refresh + empty RAS = catalogue blocker (AM). Row present = AM added the role -> works. From ce2a20e15df38b1b31dd5765867524c5d06df8cc Mon Sep 17 00:00:00 2001 From: arun Date: Fri, 24 Jul 2026 09:41:37 +0100 Subject: [PATCH 18/18] HDPI-7052: trim verbose comments on group-access config --- .../java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java | 11 +++-------- .../java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java | 5 +---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java index b4b6e1135b..c297f46be6 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/CaseType.java @@ -136,8 +136,7 @@ public void configure(final ConfigBuilder builder .organisationalRoleName(UserRole.SOLICITOR.getRole()) .liveTo("01/01/2027"); - // Org profiles per the agreed RRFM Group Access config. The SDK keeps only the - // first row per AccessTypeID, so LOCALAUTH (the test orgs' profile) must lead. + // SDK keeps only the first row per access type, so LOCALAUTH must lead. List groupAccessOrgProfiles = List.of( "LOCALAUTH_PROFILE", "SOLICITOR_PROFILE", @@ -158,21 +157,17 @@ public void configure(final ConfigBuilder builder .displayOrder(2) .liveTo("01/01/2027"); - // GroupAccessEnabled is No in the agreed config until case migration is settled; - // Yes here so the group role can be exercised on test environments. builder.accessTypeRole("prof-org-access") .organisationProfileId(orgProfile) .groupRoleName(UserRole.SOLICITOR.getRole()) .caseAssignedRoleField(UserRole.PROFESSIONAL_USER.getRole()) .groupAccessEnabled(true) - // Must start with the service name in upper case: the definition store rejects - // the lowercase template on the agreed RRFM page ("must start with 'PCS'"). + // Uppercase service prefix required; def store rejects lowercase. .caseAccessGroupIdTemplate("PCS:PCS:prof-org-access:solicitor:$ORGID$") .liveTo("01/01/2027"); } - // State-level access for the group-access profiles; without these the data store - // filters matched cases out regardless of the caseAccessGroupId key. + // State ACLs, else the data store filters matched cases out. for (State state : State.values()) { builder.grant(state, CRU, AccessProfile.SOLICITOR, AccessProfile.PROFESSIONAL_USER); } diff --git a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java index fc85f808d7..66ffd8ec7c 100644 --- a/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java +++ b/src/main/java/uk/gov/hmcts/reform/pcs/ccd/PCSCaseView.java @@ -200,10 +200,7 @@ private LocalDate getClaimIssueDateLocal(PcsCaseEntity pcsCaseEntity) { .orElse(null); } - // INTERIM: stamp the case with the group-access key so the data store's caseAccessGroupId - // matcher can grant org-wide access. Hardcoded to the WK8GIHE test org for the preview demo. - // TODO derive from the case creator's organisation (PRD lookup, persisted at create time), - // and delete once the decentralised runtime stamps CaseAccessGroups itself. + // INTERIM: hardcoded WK8GIHE stamp for preview. TODO derive from the creator's org. private void setGroupAccessFields(PCSCase pcsCase) { uk.gov.hmcts.ccd.sdk.type.CaseAccessGroup caseAccessGroup = uk.gov.hmcts.ccd.sdk.type.CaseAccessGroup.builder()