Skill: rajaryan18/artifact-signing (version 1.0.0)

--- name: artifact-signing description: A skill to sign artifacts using a digital certificate and private key. --- # Artifact Signing Skill This skill allows an AI agent to sign files, binaries, or any artifact using a PEM-encoded private key. It generates a detached signature file. ## Dependencies - Python 3.x - `cryptography` library (`pip install cryptography`) ## Tools ### `sign_artifact` Signs a given artifact with a private key. **Arguments:** - `artifact_path`: (Required) Absolute path to the file to be signed. - `key_path`: (Required) Absolute path to the PEM-encoded private key. - `output_path`: (Optional) Absolute path where the signature should be saved. Defaults to `<artifact_path>.sig`. **Example Usage:** ```powershell python c:\Docs\skills\artifact-signing\scripts\sign_artifact.py "C:\path\to\artifact.zip" "C:\path\to\private_key.pem" ``` ## Security Considerations - **Private Key Protection**: Never share your private key. Ensure the key file has restricted permissions. - **Verification**: Always verify the signature using the corresponding public key before trusting an artifact.

path: verify_skill.py
content: from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import os
import subprocess

def test_signing_flow():
    # 1. Generate test keys
    print("Generating test keys...")
    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    private_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    )
    public_pem = private_key.public_key().public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    
    with open("test_private.pem", "wb") as f: f.write(private_pem)
    with open("test_public.pem", "wb") as f: f.write(public_pem)
    
    # 2. Create a dummy artifact
    print("Creating dummy artifact...")
    artifact_content = b"This is a test artifact for signing."
    with open("test_artifact.txt", "wb") as f: f.write(artifact_content)
    
    # 3. Use the sign_artifact.py script
    print("Running sign_artifact.py...")
    script_path = os.path.join("scripts", "sign_artifact.py")
    result = subprocess.run(
        ["python", script_path, "test_artifact.txt", "test_private.pem"],
        capture_output=True, text=True
    )
    print(result.stdout)
    if result.returncode != 0:
        print(f"Error: {result.stderr}")
        return False
    
    # 4. Verify the signature
    print("Verifying signature...")
    with open("test_artifact.txt.sig", "rb") as f:
        signature = f.read()
    
    try:
        public_key = serialization.load_pem_public_key(public_pem)
        public_key.verify(
            signature,
            artifact_content,
            padding.PKCS1v15(),
            hashes.SHA256()
        )
        print("VERIFICATION SUCCESSFUL: Signature is valid!")
        return True
    except Exception as e:
        print(f"VERIFICATION FAILED: {e}")
        return False
    finally:
        # Cleanup
        for f in ["test_private.pem", "test_public.pem", "test_artifact.txt", "test_artifact.txt.sig"]:
            if os.path.exists(f): os.remove(f)

if __name__ == "__main__":
    test_signing_flow()


path: scripts/sign_artifact.py
content: import sys
import os
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization

def sign_artifact(artifact_path, key_path, output_path=None):
    """
    Signs an artifact using a private key.
    
    Args:
        artifact_path (str): Path to the artifact to sign.
        key_path (str): Path to the PEM-encoded private key.
        output_path (str, optional): Path to save the detached signature. 
                                     Defaults to artifact_path + ".sig".
    """
    if not os.path.exists(artifact_path):
        print(f"Error: Artifact not found at {artifact_path}")
        sys.exit(1)
        
    if not os.path.exists(key_path):
        print(f"Error: Private key not found at {key_path}")
        sys.exit(1)
        
    if output_path is None:
        output_path = artifact_path + ".sig"

    try:
        # Load the private key
        with open(key_path, "rb") as key_file:
            private_key = serialization.load_pem_private_key(
                key_file.read(),
                password=None, # Assuming no password for now
            )

        # Read the artifact
        with open(artifact_path, "rb") as f:
            data = f.read()

        # Sign the data
        signature = private_key.sign(
            data,
            padding.PKCS1v15(), # Traditional PKCS#1 v1.5 padding
            hashes.SHA256()
        )

        # Write the detached signature
        with open(output_path, "wb") as f:
            f.write(signature)

        print(f"Successfully signed {artifact_path}")
        print(f"Signature saved to {output_path}")

    except Exception as e:
        print(f"Error signing artifact: {e}")
        sys.exit(1)

if __name__ == "__main__":
    if len(sys.argv) < 3:
        print("Usage: python sign_artifact.py <artifact_path> <key_path> [output_path]")
        sys.exit(1)
    
    artifact = sys.argv[1]
    key = sys.argv[2]
    output = sys.argv[3] if len(sys.argv) > 3 else None
    
    sign_artifact(artifact, key, output)


path: examples/usage.md
content: # Usage Examples for Artifact Signing Skill

Below are examples of how to use the Artifact Signing skill.

## 1. Generating a Key Pair (for testing)

If you don't have a private key, you can generate one using Python:

```python
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

# Generate private key
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)

# Save private key to PEM
with open("private_key.pem", "wb") as f:
    f.write(private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    ))

# Save public key to PEM
with open("public_key.pem", "wb") as f:
    f.write(private_key.public_key().public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    ))
```

## 2. Signing an Artifact

Use the `sign_artifact.py` script to sign a file:

```powershell
python c:\Docs\skills\artifact-signing\scripts\sign_artifact.py "my_app.exe" "private_key.pem"
```

This will create `my_app.exe.sig` in the same directory.

## 3. Verifying the Signature

You can use this Python snippet to verify the signature:

```python
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization

# Load public key
with open("public_key.pem", "rb") as f:
    public_key = serialization.load_pem_public_key(f.read())

# Read artifact and signature
with open("my_app.exe", "rb") as f:
    data = f.read()
with open("my_app.exe.sig", "rb") as f:
    signature = f.read()

# Verify
try:
    public_key.verify(
        signature,
        data,
        padding.PKCS1v15(),
        hashes.SHA256()
    )
    print("Signature is valid!")
except Exception:
    print("Signature is INVALID!")
```


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)