Migration from 1.2.5 to 1.3.x
This guide contains instructions for migration from PowerAuth Server version 1.2.5
to version 1.3.x
.
Migration from release 1.2.x
of PowerAuth server to release 1.3.x
is split into two parts:
- Migration from 1.2.x to 1.2.5 - apply these steps for upgrade to version
1.2.5
- Migration from 1.2.5 to 1.3.x (this document) - apply steps below for upgrade from version
1.2.5
to version1.3.x
Change in Application ID (breaking change)
In earlier versions of PowerAuth Server, we addressed applications via their numeric (Long
) database record ID. This proved to be problematic, since the same application had different IDs on different environments. In 1.3.x and further, we now address applications via ID equal to their string name (contents of the name
column in pa_application
table), and we now call this value “application ID”.
We highly recommend renaming the application in the database by editing pa_application.name
column, so that the name is in a technical format, i.e., “mobile-token-retail”, rather than in human readable name, such as “Mobile Token For Retail Clients”.
This change is consistently reflected in all other parts of PowerAuth stack, i.e., in Push Server or Web Flow.
In case your system needs to store IDs of application, you need to reflect this change. It is no longer possible to access applications using their numeric database record ID.
Database Changes
Relation Between Operations and Applications
In a previous versions before 1.3.x, an operation could only be connected to one application. With 1.3.x, we introduced ability to add a single operation to multiple applications, and hence we are adding a new relation table. The script below creates such a table and sets the original pa_operation.application_id
column to nullable. The original column is unused, but we recommend keeping it for audit purposes.
PostgreSQL
ALTER TABLE pa_operation
ALTER COLUMN application_id DROP NOT NULL;
CREATE TABLE pa_operation_application (
application_id INTEGER NOT NULL,
operation_id VARCHAR(37) NOT NULL,
CONSTRAINT pa_operation_application_pk PRIMARY KEY (application_id, operation_id)
);
Oracle
ALTER TABLE pa_operation
MODIFY (application_id NULL);
CREATE TABLE pa_operation_application (
application_id NUMBER(19,0) NOT NULL,
operation_id VARCHAR(37) NOT NULL,
CONSTRAINT pa_operation_application_pk PRIMARY KEY (application_id, operation_id)
);
MySQL
ALTER TABLE pa_operation
MODIFY application_id BIGINT(20);
CREATE TABLE pa_operation_application (
application_id BIGINT(20) NOT NULL,
operation_id VARCHAR(37) NOT NULL,
CONSTRAINT pa_operation_application_pk PRIMARY KEY (application_id, operation_id)
);
Store Activation Version History
PostgreSQL
ALTER TABLE pa_activation_history
ADD activation_version INTEGER;
Oracle
ALTER TABLE pa_activation_history
ADD activation_version NUMBER(2,0);
MySQL
ALTER TABLE pa_activation_history
ADD activation_version INT(2);
Uniqueness Check on Application Versions
Until 1.3.x version, the pa_application_version
could contain versions of the same name for a given application. This would be a rare setup, but it needs to be reviewed before the update to 1.3.x and above. First, run the following query:
SELECT name, application_id, count(*) FROM pa_application_version GROUP BY name, application_id ORDER BY count(*);
If you can see a version with more than one duplicates, manually rename such versions in the database so that the name is unique and run the above query again. To prevent any future version duplicities, we also recommend creating the following unique index:
PostgreSQL
CREATE UNIQUE INDEX pa_application_name_index
ON pa_application_version (application_id, name);
Oracle
CREATE UNIQUE INDEX pa_application_name_index
ON pa_application_version (application_id, name);
MySQL
CREATE UNIQUE INDEX pa_application_name_index
ON pa_application_version (application_id, name);
Create Auditing Tables
Create tables for auditing:
audit_log
- table used to store audit logsaudit_param
- table used to store detailed parameters for audit logs
The auditing tables may be already present in your database schema in case the database schema is not separated for different PowerAuth applications. You might have also added these tables as part of migration to release 1.2.5
before these duplicate migration instructions were removed. In case tables audit_log
and audit_param
are already present, you can safely skip this migration step.
Oracle
--
-- Create audit log table.
--
CREATE TABLE audit_log (
audit_log_id VARCHAR2(36 CHAR) PRIMARY KEY,
application_name VARCHAR2(256 CHAR) NOT NULL,
audit_level VARCHAR2(32 CHAR) NOT NULL,
audit_type VARCHAR2(256 CHAR),
timestamp_created TIMESTAMP,
message CLOB NOT NULL,
exception_message CLOB,
stack_trace CLOB,
param CLOB,
calling_class VARCHAR2(256 CHAR) NOT NULL,
thread_name VARCHAR2(256 CHAR) NOT NULL,
version VARCHAR2(256 CHAR),
build_time TIMESTAMP
);
--
-- Create audit parameters table.
--
CREATE TABLE audit_param (
audit_log_id VARCHAR2(36 CHAR),
timestamp_created TIMESTAMP,
param_key VARCHAR2(256 CHAR),
param_value VARCHAR2(4000 CHAR)
);
--
-- Create indexes.
--
CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created);
CREATE INDEX audit_log_application ON audit_log (application_name);
CREATE INDEX audit_log_level ON audit_log (audit_level);
CREATE INDEX audit_log_type ON audit_log (audit_type);
CREATE INDEX audit_param_log ON audit_param (audit_log_id);
CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created);
CREATE INDEX audit_param_key ON audit_param (param_key);
CREATE INDEX audit_param_value ON audit_param (param_value);
PostgreSQL
--
-- Create audit log table.
--
CREATE TABLE IF NOT EXISTS audit_log (
audit_log_id VARCHAR(36) PRIMARY KEY,
application_name VARCHAR(256) NOT NULL,
audit_level VARCHAR(32) NOT NULL,
audit_type VARCHAR(256),
timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
message TEXT NOT NULL,
exception_message TEXT,
stack_trace TEXT,
param TEXT,
calling_class VARCHAR(256) NOT NULL,
thread_name VARCHAR(256) NOT NULL,
version VARCHAR(256),
build_time TIMESTAMP
);
--
-- Create audit parameters table.
--
CREATE TABLE IF NOT EXISTS audit_param (
audit_log_id VARCHAR(36),
timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
param_key VARCHAR(256),
param_value VARCHAR(4000)
);
--
-- Create indexes.
--
CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created);
CREATE INDEX audit_log_application ON audit_log (application_name);
CREATE INDEX audit_log_level ON audit_log (audit_level);
CREATE INDEX audit_log_type ON audit_log (audit_type);
CREATE INDEX audit_param_log ON audit_param (audit_log_id);
CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created);
CREATE INDEX audit_param_key ON audit_param (param_key);
CREATE INDEX audit_param_value ON audit_param (param_value);
MySQL
--
-- Create audit log table.
--
CREATE TABLE IF NOT EXISTS audit_log (
audit_log_id VARCHAR(36) PRIMARY KEY,
application_name VARCHAR(256) NOT NULL,
audit_level VARCHAR(32) NOT NULL,
audit_type VARCHAR(256),
timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
message TEXT NOT NULL,
exception_message TEXT,
stack_trace TEXT,
param TEXT,
calling_class VARCHAR(256) NOT NULL,
thread_name VARCHAR(256) NOT NULL,
version VARCHAR(256),
build_time TIMESTAMP NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
--
-- Create audit parameters table.
--
CREATE TABLE IF NOT EXISTS audit_param (
audit_log_id VARCHAR(36),
timestamp_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
param_key VARCHAR(256),
param_value VARCHAR(3072)
) ENGINE=InnoDB AUTO_INCREMENT=1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
--
-- Create indexes.
--
CREATE INDEX audit_log_timestamp ON audit_log (timestamp_created);
CREATE INDEX audit_log_application ON audit_log (application_name);
CREATE INDEX audit_log_level ON audit_log (audit_level);
CREATE INDEX audit_log_type ON audit_log (audit_type);
CREATE INDEX audit_param_log ON audit_param (audit_log_id);
CREATE INDEX audit_param_timestamp ON audit_param (timestamp_created);
CREATE INDEX audit_param_key ON audit_param (param_key);
CREATE FULLTEXT INDEX audit_param_value ON audit_param (param_value);
Extended Activation Expiration
This change may have security implications for your deployment. Please read through the description carefully.
We extended the default activation expiration interval from 2 minutes to 5 minutes. This means that there is a larger time frame between creating the activation (initActivation
) and committing it (commitActivation
) on the server side. We made this change because of a repeated feedback from the developers and testers, who struggled to perform necessary tasks within the 2-minute interval in a non-production environment which - unlike the production setup - is not frictionless.
We consider the 5-minute interval to still be safe, since the relatively high activation code entropy does not allow for a simple brute force attacks. However, should you have any security concerns, you can change the activation expiration time interval back to 2 minutes by setting the following property:
powerauth.service.crypto.activationValidityInMilliseconds=120000
Database Dialect Configuration
The latest release of PowerAuth requires configuration of database dialect.
The dialect is specified using following configuration property:
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect
Use the most specific dialect, if possible, such as:
org.hibernate.dialect.Oracle12cDialect
for Oracle 12c or higherorg.hibernate.dialect.PostgreSQL95Dialect
for PostgreSQL 9.5 or higher
You can find additional database dialects in Hibernate documentation.