Dynamic Change Request
A Dynamic Change Request is a proposed create, update or delete of a runtime-defined artefact that carries code or configuration - a here, a here, a here or an ABAC Rule - held for approval by a second person. It is how OBP implements maker/checker for dynamic code.
Why
A Dynamic Resource Doc method body, a Connector Method or a Dynamic Message Doc is user-supplied code compiled and run inside the OBP-API JVM, with the connector credentials and reach of the whole instance. The primary control is that the person who writes the code (the maker) can never make it live alone: a different User holding the Role CanApproveDynamicChangeRequest (the checker) reviews the exact definition and approves it.
How it works when approval is on
-
The maker calls the usual v4.0.0 / v6.0.0 create, update or delete endpoint. OBP checks the maker's Role, validates the JSON and compiles the code exactly as before, but instead of applying the change it stores a Dynamic Change Request and answers
202 Acceptedwith the request instead of the artefact. Nothing is served yet. -
The checker reads the request (
GET /obp/v7.0.0/management/dynamic-change-requests/CHANGE_REQUEST_ID, which returns the proposed and the current payload side by side) and approves it by quoting itspayload_hash, the SHA-256 of the exact body, onPOST .../approval. Only then is the change applied. OBP refuses an approval from the User who made the request (OBP-30279). -
An approval covers the exact code. Any later edit produces a new hash and needs a new approval. The runtime compiles and serves only rows whose code hash equals the hash a checker approved. The code hash covers the programming language as well as the method body, and is recomputed from the row each time, so a row whose body or language is edited directly in the database does not run.
-
Deactivating an artefact is a direct action by a single checker (
POST .../deactivation), with no request: four eyes to enable, one pair to disable. Enabling it again goes through a request.
Approval is system level. Dynamic code runs in the shared JVM, so a bank-level artefact is approved by the same system-level checker; there are no bank-level change request endpoints.
Statuses
INITIATED- waiting for a checker. Approve, reject and withdraw apply only in this status.APPROVED- applied; the artefact is compiled and served.REJECTED- declined by a checker with a comment. Nothing was applied.WITHDRAWN- taken back by the maker.EXPIRED- no checker acted within the request time-to-live.FAILED- approved, but applying the change threw. The error is recorded on the request and nothing half-applied is served.
Endpoints (v7.0.0, tag Dynamic-Change-Request)
GET /management/dynamic-code-approval-config- whether approval is on, for which target types, and the request time-to-live. Any authenticated User; what a client reads to warn a maker before they submit.GET /my/dynamic-change-requests- the caller's own requests. No Role.GET /management/dynamic-change-requestsandGET .../CHANGE_REQUEST_ID- all requests, filterable bystatus,target_type,target_idandrequestor_user_id. RoleCanGetDynamicChangeRequests.POST /management/dynamic-change-requests- submit a request explicitly with abusiness_justification, for tooling; the maker's usual create call does this implicitly.POST .../CHANGE_REQUEST_ID/approval,.../rejection(comment required),.../withdrawal(maker only).POST /management/dynamic-resource-docs/ID/deactivationand the equivalents for dynamic message docs, connector methods and ABAC rules.
Operator settings (props)
allow_user_generated_scala_code- the kill switch for all runtime-compiled code. Default false: every create or update of dynamic code fails withOBP-50020and nothing dynamic runs, whatever the settings below say. Read once at startup, so changing it needs a restart.dynamic_code_requires_approval- the approval switch. Default false: writes go live immediately, today's behaviour.dynamic_code_approval_target_types- which target types are gated. DefaultDYNAMIC_RESOURCE_DOC,DYNAMIC_MESSAGE_DOC,CONNECTOR_METHOD,ABAC_RULE.dynamic_code_delete_requires_approval- whether deletes are queued too. Default true; deleting does not expand capability but does break consumers.dynamic_code_approval_request_ttl_hours-INITIATEDrequests older than this becomeEXPIREDwhen next read. 0 disables expiry. Default 168.
The first start with dynamic_code_requires_approval=true seeds the approved hash of every pre-existing row from its current body, once per database, so nothing that is live today stops working. After that the only way a row becomes executable is a checker's approval.
See here for how the gated artefacts relate to each other.