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 → Use observability.logs.level
  • jacs_log_file → Use observability.logs.destination

Migration Steps

  1. Update Configuration:

    # Backup current config
    cp jacs.config.json jacs.config.json.backup
    
    # Update to new format
    # Add observability section if needed
    
  2. Update Dependencies:

    # Node.js
    npm install jacsnpm@latest
    
    # Python
    pip install --upgrade jacs
    
  3. Verify Existing Documents:

    jacs document verify -d ./jacs_data/documents/
    

Migrating Storage Backends

Filesystem to AWS S3

  1. Create S3 Bucket:

    aws s3 mb s3://my-jacs-bucket
    
  2. Update Configuration:

    {
      "jacs_default_storage": "aws",
      "jacs_data_directory": "s3://my-jacs-bucket/data"
    }
    
  3. Set Environment Variables:

    export AWS_ACCESS_KEY_ID="your-key"
    export AWS_SECRET_ACCESS_KEY="your-secret"
    export AWS_REGION="us-east-1"
    
  4. Migrate Documents:

    # Upload existing documents
    aws s3 sync ./jacs_data/ s3://my-jacs-bucket/data/
    
  5. Verify Migration:

    jacs document verify -d s3://my-jacs-bucket/data/documents/
    

AWS S3 to Filesystem

  1. Download Documents:

    aws s3 sync s3://my-jacs-bucket/data/ ./jacs_data/
    
  2. Update Configuration:

    {
      "jacs_default_storage": "fs",
      "jacs_data_directory": "./jacs_data"
    }
    
  3. 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.

  1. Create New Agent with New Algorithm:

    {
      "jacs_agent_key_algorithm": "pq-dilithium"
    }
    
    jacs agent create --create-keys true -f new-agent.json
    
  2. Update Configuration:

    {
      "jacs_agent_key_algorithm": "pq-dilithium",
      "jacs_agent_id_and_version": "new-agent-id:new-version"
    }
    
  3. 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:

  1. Export Agent Files:

    jacs_keys/
    ├── private.pem
    └── public.pem
    jacs.config.json
    
  2. 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

  1. 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
    
  2. Update Configuration:

    {
      "jacs_agent_private_key_filename": "private.pem"
    }
    
  3. Set Password:

    export JACS_PRIVATE_KEY_PASSWORD="your-secure-password"
    

Database Migration

Adding Database Storage

If migrating from filesystem to include database storage:

  1. 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)
    );
    
  2. 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

  1. Install JACS:

    npm install jacsnpm
    
  2. 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);
    
  3. 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

  1. Install Middleware:

    npm install jacsnpm
    
  2. 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());
    
  3. 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:

  1. Verify Configuration:

    jacs config read
    
  2. Verify Agent:

    jacs agent verify
    
  3. Verify Sample Document:

    jacs document verify -f ./sample-doc.json
    
  4. Test Document Creation:

    echo '{"test": true}' > test.json
    jacs document create -f test.json
    
  5. Verify Version:

    jacs version
    

Rollback Procedures

If migration fails:

  1. Restore Configuration:

    cp jacs.config.json.backup jacs.config.json
    
  2. Restore Keys:

    cp -r jacs_keys.backup/* jacs_keys/
    
  3. Restore Dependencies:

    # Node.js
    npm install jacsnpm@previous-version
    
    # Python
    pip install jacs==previous-version
    
  4. Verify Rollback:

    jacs agent verify
    jacs document verify -d ./jacs_data/documents/
    

See Also