Migration Guide
This guide covers migrating between JACS versions and common migration scenarios.
Version Compatibility
JACS maintains backward compatibility for document verification:
- Documents signed with older versions can be verified with newer versions
- Older JACS versions cannot verify documents using newer cryptographic algorithms
Migrating from 0.2.x to 0.3.x
Configuration Changes
New Configuration Fields:
{
"observability": {
"logs": { "enabled": true, "level": "info" },
"metrics": { "enabled": false },
"tracing": { "enabled": false }
}
}
Deprecated Fields:
jacs_log_level→ Useobservability.logs.leveljacs_log_file→ Useobservability.logs.destination
Migration Steps
-
Update Configuration:
# Backup current config cp jacs.config.json jacs.config.json.backup # Update to new format # Add observability section if needed -
Update Dependencies:
# Node.js npm install jacsnpm@latest # Python pip install --upgrade jacs -
Verify Existing Documents:
jacs document verify -d ./jacs_data/documents/
Migrating Storage Backends
Filesystem to AWS S3
-
Create S3 Bucket:
aws s3 mb s3://my-jacs-bucket -
Update Configuration:
{ "jacs_default_storage": "aws", "jacs_data_directory": "s3://my-jacs-bucket/data" } -
Set Environment Variables:
export AWS_ACCESS_KEY_ID="your-key" export AWS_SECRET_ACCESS_KEY="your-secret" export AWS_REGION="us-east-1" -
Migrate Documents:
# Upload existing documents aws s3 sync ./jacs_data/ s3://my-jacs-bucket/data/ -
Verify Migration:
jacs document verify -d s3://my-jacs-bucket/data/documents/
AWS S3 to Filesystem
-
Download Documents:
aws s3 sync s3://my-jacs-bucket/data/ ./jacs_data/ -
Update Configuration:
{ "jacs_default_storage": "fs", "jacs_data_directory": "./jacs_data" } -
Verify Documents:
jacs document verify -d ./jacs_data/documents/
Migrating Cryptographic Algorithms
Ed25519 to Post-Quantum
For increased security, you may want to migrate to post-quantum algorithms.
-
Create New Agent with New Algorithm:
{ "jacs_agent_key_algorithm": "pq-dilithium" }jacs agent create --create-keys true -f new-agent.json -
Update Configuration:
{ "jacs_agent_key_algorithm": "pq-dilithium", "jacs_agent_id_and_version": "new-agent-id:new-version" } -
Re-sign Critical Documents (Optional):
// Re-sign documents with new algorithm const oldDoc = JSON.parse(fs.readFileSync('./old-doc.json')); // Remove old signature fields delete oldDoc.jacsSignature; delete oldDoc.jacsSha256; // Create new signed version const newDoc = await agent.createDocument(JSON.stringify(oldDoc));
Note: Old documents remain valid with old signatures. Re-signing is only needed for documents that require the new algorithm.
Migrating Between Platforms
Node.js to Python
Both platforms use the same document format:
// Node.js - create document
const signedDoc = await agent.createDocument(JSON.stringify(content));
fs.writeFileSync('doc.json', signedDoc);
# Python - verify the same document
with open('doc.json', 'r') as f:
doc_string = f.read()
is_valid = agent.verify_document(doc_string)
Sharing Agents Between Platforms
Agents can be used across platforms by sharing configuration:
-
Export Agent Files:
jacs_keys/ ├── private.pem └── public.pem jacs.config.json -
Use Same Config in Both:
// Node.js await agent.load('./jacs.config.json');# Python agent.load('./jacs.config.json')
Migrating Key Formats
Unencrypted to Encrypted Keys
-
Encrypt Existing Key:
# Backup original cp jacs_keys/private.pem jacs_keys/private.pem.backup # Encrypt with password openssl pkcs8 -topk8 -in jacs_keys/private.pem \ -out jacs_keys/private.pem.enc -v2 aes-256-cbc # Remove unencrypted key rm jacs_keys/private.pem mv jacs_keys/private.pem.enc jacs_keys/private.pem -
Update Configuration:
{ "jacs_agent_private_key_filename": "private.pem" } -
Set Password:
export JACS_PRIVATE_KEY_PASSWORD="your-secure-password"
Database Migration
Adding Database Storage
If migrating from filesystem to include database storage:
-
Create Database Schema:
CREATE TABLE jacs_documents ( id UUID PRIMARY KEY, version_id UUID NOT NULL, document JSONB NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), UNIQUE(id, version_id) ); -
Import Existing Documents:
const fs = require('fs'); const path = require('path'); const { Pool } = require('pg'); const pool = new Pool({ connectionString: process.env.DATABASE_URL }); const docsDir = './jacs_data/documents'; async function importDocuments() { const docDirs = fs.readdirSync(docsDir); for (const docId of docDirs) { const docPath = path.join(docsDir, docId); const versions = fs.readdirSync(docPath); for (const versionFile of versions) { const docString = fs.readFileSync( path.join(docPath, versionFile), 'utf-8' ); const doc = JSON.parse(docString); await pool.query(` INSERT INTO jacs_documents (id, version_id, document) VALUES ($1, $2, $3) ON CONFLICT (id, version_id) DO NOTHING `, [doc.jacsId, doc.jacsVersion, doc]); } } } importDocuments();
MCP Integration Migration
Adding JACS to Existing MCP Server
-
Install JACS:
npm install jacsnpm -
Wrap Existing Transport:
// Before const transport = new StdioServerTransport(); await server.connect(transport); // After import { createJACSTransportProxy } from 'jacsnpm/mcp'; const baseTransport = new StdioServerTransport(); const secureTransport = createJACSTransportProxy( baseTransport, './jacs.config.json', 'server' ); await server.connect(secureTransport); -
Update Client:
// Client also needs JACS const baseTransport = new StdioClientTransport({ command: 'node', args: ['server.js'] }); const secureTransport = createJACSTransportProxy( baseTransport, './jacs.client.config.json', 'client' ); await client.connect(secureTransport);
HTTP API Migration
Adding JACS to Existing Express API
-
Install Middleware:
npm install jacsnpm -
Add Middleware to Routes:
import { JACSExpressMiddleware } from 'jacsnpm/http'; // Before app.use('/api', express.json()); // After - for JACS-protected routes app.use('/api/secure', express.text({ type: '*/*' })); app.use('/api/secure', JACSExpressMiddleware({ configPath: './jacs.config.json' })); // Keep non-JACS routes unchanged app.use('/api/public', express.json()); -
Update Route Handlers:
// Before app.post('/api/data', (req, res) => { const payload = req.body; // ... }); // After app.post('/api/secure/data', (req, res) => { const payload = req.jacsPayload; // Verified payload // ... });
Troubleshooting Migration
Common Issues
Documents Not Verifying After Migration:
- Check algorithm compatibility
- Verify keys were copied correctly
- Ensure configuration paths are correct
Key File Errors:
- Verify file permissions (600 for private key)
- Check key format matches algorithm
- Ensure password is set for encrypted keys
Storage Errors After Migration:
- Verify storage backend is accessible
- Check credentials/permissions
- Ensure directory structure is correct
Verification Checklist
After any migration:
-
Verify Configuration:
jacs config read -
Verify Agent:
jacs agent verify -
Verify Sample Document:
jacs document verify -f ./sample-doc.json -
Test Document Creation:
echo '{"test": true}' > test.json jacs document create -f test.json -
Verify Version:
jacs version
Rollback Procedures
If migration fails:
-
Restore Configuration:
cp jacs.config.json.backup jacs.config.json -
Restore Keys:
cp -r jacs_keys.backup/* jacs_keys/ -
Restore Dependencies:
# Node.js npm install jacsnpm@previous-version # Python pip install jacs==previous-version -
Verify Rollback:
jacs agent verify jacs document verify -d ./jacs_data/documents/
See Also
- Configuration Reference - Configuration options
- Cryptographic Algorithms - Algorithm details
- Storage Backends - Storage options