Skip to content

Commit 61832f9

Browse files
Migrate persistence to PostgreSQL and manage secrets with Vault (#35)
Use PostgreSQL with the jOOQ Open Source Edition to avoid requiring a commercial license for Oracle dialect support. Keep service databases and runtime/migration privileges isolated. Add vendor-specific Flyway schemas, Vault AppRole and scoped application secrets, dynamic credential pool replacement, and OTP concurrency checks. Preserve historical Oracle scripts and document cutover, key rotation, local verification and remaining limitations. Include only migration work; the separately owned Identity foundation remains a dependency.
1 parent 552040d commit 61832f9

94 files changed

Lines changed: 6529 additions & 489 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.dockerignore‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.git
2+
.idea
3+
.agents
4+
.codex
5+
.aws
6+
.ssh
7+
.env
8+
.env.*
9+
.local
10+
**/target
11+
**/__pycache__

‎.env.example‎

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,7 @@
1+
# Secrets are generated into ignored protected files by scripts/local/prepare.py.
2+
# No runtime database passwords or HMAC keys belong here.
13
COMPOSE_PROJECT_NAME=payguard
2-
3-
ORACLE_IMAGE=gvenzl/oracle-free:23-slim-faststart
4-
WALLET_ORACLE_PORT=1521
5-
LOAN_ORACLE_PORT=1522
6-
COLLATERAL_ORACLE_PORT=1523
7-
WALLET_ORACLE_SYSTEM_PASSWORD=change-wallet-system-password
8-
LOAN_ORACLE_SYSTEM_PASSWORD=change-loan-system-password
9-
COLLATERAL_ORACLE_SYSTEM_PASSWORD=change-collateral-system-password
10-
WALLET_ORACLE_APP_USER=payguard_wallet
11-
LOAN_ORACLE_APP_USER=payguard_loan
12-
COLLATERAL_ORACLE_APP_USER=payguard_collateral
13-
WALLET_ORACLE_APP_PASSWORD=change-wallet-app-password
14-
LOAN_ORACLE_APP_PASSWORD=change-loan-app-password
15-
COLLATERAL_ORACLE_APP_PASSWORD=change-collateral-app-password
16-
WALLET_ORACLE_JDBC_URL=jdbc:oracle:thin:@localhost:1521/FREE
17-
LOAN_ORACLE_JDBC_URL=jdbc:oracle:thin:@localhost:1522/FREE
18-
COLLATERAL_ORACLE_JDBC_URL=jdbc:oracle:thin:@localhost:1523/FREE
19-
OTP_ORACLE_PORT=1524
20-
OTP_ORACLE_SYSTEM_PASSWORD=change-otp-system-password
21-
OTP_ORACLE_APP_USER=payguard_otp
22-
OTP_ORACLE_APP_PASSWORD=change-otp-app-password
23-
OTP_ORACLE_JDBC_URL=jdbc:oracle:thin:@localhost:1524/FREE
24-
OTP_SECURITY_PEPPER=replace-with-a-random-secret-at-least-32-characters
25-
OTP_SERVICE_PORT=8084
26-
REDIS_HOST=localhost
27-
REDIS_PORT=6379
28-
29-
WALLET_SERVICE_PORT=8081
30-
LOAN_SERVICE_PORT=8082
31-
COLLATERAL_SERVICE_PORT=8083
32-
33-
KAFKA_IMAGE=apache/kafka:latest
4+
VAULT_PORT=8200
345
KAFKA_PORT=9092
35-
KAFKA_CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk
36-
KAFKA_BOOTSTRAP_SERVERS=localhost:9092
6+
PAYGUARD_LOCAL_UID=1000
7+
PAYGUARD_LOCAL_GID=1000
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: PostgreSQL and Vault verification
2+
3+
on:
4+
workflow_call:
5+
6+
permissions:
7+
contents: read
8+
9+
jobs:
10+
real-dependencies:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 25
13+
steps:
14+
- uses: actions/checkout@v7
15+
- uses: actions/setup-java@v6
16+
with:
17+
distribution: temurin
18+
java-version: '25'
19+
cache: maven
20+
- name: PostgreSQL migrations and competing transactions
21+
run: >-
22+
./mvnw -B -ntp -pl payguard-identity-service,payguard-loan-service,payguard-collateral-service -am
23+
-Dtest=PostgreSqlTlsTest,PostgresqlMigrationRehearsalTest,SanitizedDependencyErrorTest,OtpInfrastructureIntegrationTest,OtpApplicationContractsTest,LoanServiceApplicationTests,CollateralServiceApplicationTests
24+
-Dsurefire.failIfNoSpecifiedTests=false clean test
25+
- name: Build protected migration and integration runners
26+
run: >-
27+
./mvnw -B -ntp -pl payguard-identity-service,payguard-wallet-service,payguard-loan-service,payguard-collateral-service -am -DskipTests package dependency:copy-dependencies -DincludeScope=test
28+
- name: Verify synthetic export and approved identifier mapping
29+
run: python3 -m unittest discover -s scripts/migration -p 'test_*.py'
30+
- name: Prepare isolated TLS infrastructure
31+
run: |
32+
python3 scripts/local/prepare.py
33+
docker compose --env-file .env.example up -d --wait postgres-wallet postgres-loan postgres-collateral postgres-identity vault
34+
python3 scripts/local/vault_bootstrap.py
35+
- name: Apply separately privileged Flyway migrations
36+
run: |
37+
python3 scripts/local/migrate.py identity
38+
python3 scripts/local/migrate.py loan
39+
python3 scripts/local/migrate.py collateral
40+
- name: Verify actual pools, scoped secrets and Vault audit
41+
run: python3 scripts/local/verify_vault.py
42+
- name: Boot actual packaged services with scoped credentials
43+
run: python3 scripts/local/verify_applications.py
44+
- name: Preserve test reports
45+
if: always()
46+
uses: actions/upload-artifact@v7
47+
with:
48+
name: database-security-reports
49+
path: |
50+
**/target/surefire-reports/TEST-*.xml
51+
payguard-shared/target/vault-test-reports/*.xml
52+
if-no-files-found: warn
53+
- name: Stop isolated infrastructure
54+
if: always()
55+
run: docker compose --env-file .env.example stop

‎.github/workflows/_publish.yml‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@ jobs:
3434
| grep -A8 -B2 spring-boot-maven-plugin
3535
3636
- name: Build Wallet Service Image
37-
run: docker build -f payguard-wallet-service/Dockerfile -t payguard/wallet-service:latest .
37+
run: docker build -f payguard-wallet-service/Dockerfile -t payguard/wallet-service:${{ github.sha }} .
3838

3939
- name: Build Loan Service Image
40-
run: docker build -f payguard-loan-service/Dockerfile -t payguard/loan-service:latest .
40+
run: docker build -f payguard-loan-service/Dockerfile -t payguard/loan-service:${{ github.sha }} .
4141

4242
- name: Build Collateral Service Image
43-
run: docker build -f payguard-collateral-service/Dockerfile -t payguard/collateral-service:latest .
43+
run: docker build -f payguard-collateral-service/Dockerfile -t payguard/collateral-service:${{ github.sha }} .
44+
45+
- name: Build Identity Service Image
46+
run: docker build -f payguard-identity-service/Dockerfile -t payguard/identity-service:${{ github.sha }} .

‎.github/workflows/pipeline.yml‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ on:
77
types: [ opened, reopened, synchronize ]
88

99
jobs:
10+
database-security:
11+
uses: ./.github/workflows/_database-security.yml
12+
1013
# 1. Always run quality checks on PRs and main branch pushes
1114
quality-check:
1215
uses: ./.github/workflows/_quality.yml
1316

1417
# 2. Build container images on every PR and main push.
1518
# This job validates images; it does not publish to an external registry.
1619
publish-docker:
17-
needs: quality-check
20+
needs: [quality-check, database-security]
1821
uses: ./.github/workflows/_publish.yml

‎.gitignore‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ target/
88

99
# Local workflow guidance
1010
GIT_WORKFLOW_CONVENTION.md
11+
PAYGUARD_GOAL.md
12+
13+
# Protected local PostgreSQL/Vault rehearsal artifacts
14+
.local/
15+
__pycache__/

0 commit comments

Comments
 (0)