Skip to content

Flow 17 --- Rapid Revocation Lifecycle (Non-Streaming)

This scenario walks through an instant key-revocation cycle with an RSA-3072 key:

  1. Generate a new RSA-3072 key (kty="RSA", alg="RSA-3072").

  2. Sign a plaintext file → compact JWS (non-streaming helper).

  3. Revoke the key immediately.

  4. Attempt a second signature --- the SDK must raise AnkaSecureSdkException.

  5. Export the key metadata and verify the flag status = REVOKED.

Key points

  • Illustrates how to invalidate a compromised key in real time.

  • Demonstrates that post-revocation crypto operations are blocked by the platform.

  • Shows how to prove revocation via a metadata export.

  • Keeps all artefacts inside temp_files/ so your workspace stays clean.

When to use it

  • Incident response drills -- rehearse the immediate kill-switch procedure for leaked signing keys.

  • Compliance evidence -- provide auditors with a repeatable test that revocation is enforced.

  • Operational monitoring -- integrate into CI to ensure revoked keys cannot be reused accidentally.

Shared helper – this code imports the utility class from
example_util.md (configuration, authentication, JSON).


Complete Java implementation

src/main/java/co/ankatech/ankasecure/sdk/examples/ExampleScenario17.java

/*
 * Copyright 2025 ANKATech Solutions Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */
/* *****************************************************************************
 * FILE: ExampleScenario17.java
 * ****************************************************************************/
package co.ankatech.ankasecure.sdk.examples;

import co.ankatech.ankasecure.sdk.AnkaSecureSdk;
import co.ankatech.ankasecure.sdk.exception.AnkaSecureSdkException;
import co.ankatech.ankasecure.sdk.model.ExportedKeySpec;
import co.ankatech.ankasecure.sdk.model.GenerateKeySpec;
import co.ankatech.ankasecure.sdk.model.SignResult;
import co.ankatech.ankasecure.sdk.util.FileIO;

import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.Properties;

import static co.ankatech.ankasecure.sdk.examples.ExampleUtil.*;

/**
 * <h2>Scenario&nbsp;17 – Rapid Revocation Lifecycle (Compact&nbsp;JWS)</h2>
 *
 * <p>This scenario validates that once an RSA-3072 key is revoked, subsequent
 * signing requests with the same <code>kid</code> are rejected:</p>
 * <ol>
 *   <li>Generate an RSA-3072 key.</li>
 *   <li>Create a first compact&nbsp;JWS.</li>
 *   <li>Revoke the key.</li>
 *   <li>Attempt a second signature (should fail).</li>
 *   <li>Export the key metadata and confirm <code>status&nbsp;=&nbsp;REVOKED</code>.</li>
 * </ol>
 *
 * @author ANKATech – Security Engineering
 * @since 2.1.0
 */
public final class ExampleScenario17 {
    /* ====================================================================== */
    /** Entry-point. */
    public static void main(final String[] args) {

        System.out.println("===== SCENARIO 17 START =====");
        System.out.println("""
                Purpose :
                  * Generate RSA-3072, sign once, revoke, then confirm blocking.
                Steps   :
                  1) Generate RSA-3072 key
                  2) Sign a file (compact JWS)
                  3) Revoke key
                  4) Attempt second sign (should fail)
                  5) Export and verify status = REVOKED
                --------------------------------------------------------------""");

        try {
            ensureTempDir(TEMP_DIR);

            Properties props = loadProperties();
            AnkaSecureSdk sdk = authenticate(props);

            runScenario(sdk);

        } catch (Exception ex) {
            fatal("Scenario 17 failed", ex);
        }

        System.out.println("===== SCENARIO 17 END =====");
    }

    /* ====================================================================== */
    /** Executes the scenario logic. */
    private static void runScenario(final AnkaSecureSdk sdk) throws Exception {

        /* 0 ── prepare sample file -------------------------------------- */
        Path data = TEMP_DIR.resolve("scenario17_data.txt");
        FileIO.writeUtf8(
                data,
                "Scenario 17 – RSA-3072 rapid revocation demo.");
        System.out.println("[0] Data file prepared      -> " + data.toAbsolutePath());

        /* 1 ── generate RSA-3072 key ----------------------------------- */
        String kid = "sc17_rsa3072_" + System.currentTimeMillis();
        sdk.generateKey(new GenerateKeySpec()
                .setKid(kid)
                .setKty("RSA")
                .setAlg("RSA-3072"));
        System.out.println("[1] Key generated           -> kid = " + kid);

        /* 2 ── sign file successfully ---------------------------------- */
        Path sig1 = TEMP_DIR.resolve("scenario17_sig1.jws");
        SignResult meta1 = sdk.signFile(kid, data, sig1);
        System.out.println("[2] First signature created -> " + sig1.toAbsolutePath());
        printSignMeta(meta1);

        /* 3 ── revoke key ---------------------------------------------- */
        sdk.revokeKey(kid);
        System.out.println("[3] Key revoked             -> kid = " + kid);

        /* 4 ── attempt second sign (expect failure) -------------------- */
        try {
            Path sig2 = TEMP_DIR.resolve("scenario17_sig2.jws");
            sdk.signFile(kid, data, sig2);
            System.err.println("[4] ERROR – signing succeeded after revocation!");
        } catch (AnkaSecureSdkException ex) {
            System.out.println(MessageFormat.format(
                    "[4] Expected failure -> HTTP={0}, message={1}",
                    ex.getHttpStatus(), ex.getMessage()));
        }

        /* 5 ── export metadata and confirm status ---------------------- */
        ExportedKeySpec exported = sdk.exportKey(kid);
        System.out.println("[5] Exported key status     -> " + exported.getStatus());
    }

    /**
     * Private constructor prevents instantiation.
     */
    private ExampleScenario17() {
        /* utility class – no instantiation */
    }
}

How to run

mvn -q compile exec:java\
  -Dexec.mainClass="co.ankatech.ankasecure.sdk.examples.ExampleScenario17"

Console milestones

  • RSA-3072 key generation

  • First compact-JWS signature

  • Key revocation

  • Expected failure on second sign (AnkaSecureSdkException)

  • Export shows status = REVOKED


Where next?

© 2025 ANKATech Solutions INC. All rights reserved.