DevOps Guide
Automate certificate pin management in production environments using the TrustPin CLI. This guide covers the complete workflow for managing certificate pins from installation to automated CI/CD deployments.
Overview
TrustPin uses a two-step process for certificate pin updates:
- Upsert: Add or update certificate pins in your project configuration
- Sign: Cryptographically sign the configuration and publish it to the CDN
This separation allows you to:
- Stage multiple pin changes before publishing
- Review configuration changes before they go live
- Maintain an audit trail of all pin modifications
- Use different security controls for staging vs. publishing
Quick Start
1. Install the CLI
Homebrew (Recommended):
brew tap trustpin-cloud/trustpin-cli
brew install trustpin-cliDirect Download (Linux x64 for CI/CD):
curl -L https://github.com/trustpin-cloud/homebrew-trustpin/releases/latest/download/trustpin-cli-linux-x64 -o trustpin-cli
chmod +x trustpin-cli
sudo mv trustpin-cli /usr/local/bin/See Installation for platform-specific instructions.
2. Configure Authentication
Set the TRUSTPIN_API_TOKEN environment variable:
export TRUSTPIN_API_TOKEN="tp_your_token_here"Get your Personal Access Token from TrustPin Console .
The CLI automatically uses this environment variable when available.
3. Get Your Project IDs
# List all projects
trustpin-cli projects list
# Get IDs in JSON format
trustpin-cli projects list --output json | jq -r '.data.projects[] | "\(.organization_id) \(.id) \(.name)"'Note your Organization ID and Project ID for subsequent commands.
Certificate Pin Management Workflow
Step 1: Extract Pin from Certificate
Extract the SPKI SHA-256 fingerprint and expiration date from your certificate:
#!/bin/bash
CERT_FILE="cert.pem"
# Extract SPKI SHA-256 (OWASP recommended - pins the public key)
SPKI_SHA256=$(openssl x509 -in "$CERT_FILE" -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64)
# Extract expiration date (portable across Linux/macOS)
EXPIRES_EPOCH=$(openssl x509 -in "$CERT_FILE" -noout -enddate | \
cut -d= -f2 | \
xargs -I{} date -jf "%b %d %H:%M:%S %Y %Z" "{}" +%s 2>/dev/null || \
date -d "$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)" +%s)
EXPIRES=$(date -u -r "$EXPIRES_EPOCH" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || \
date -u -d "@$EXPIRES_EPOCH" +%Y-%m-%dT%H:%M:%SZ)
echo "SPKI SHA-256: $SPKI_SHA256"
echo "Expires: $EXPIRES"Example output:
SPKI SHA-256: oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o=
Expires: 2026-04-13T08:37:02ZStep 2: Upsert the Pin
Add or update the certificate pin in your project configuration:
trustpin-cli projects upsert \
<organization-id> \
<project-id> \
--domain api.example.com \
--pin spki-sha256:$SPKI_SHA256 \
--expires $EXPIRES \
--output jsonExample output:
{
"status": "success",
"operation": "upsert",
"domain": "api.example.com",
"action": "added",
"pin": {
"type": "spki-sha256",
"value": "oxVSdCLgthL3M5Vnnzepq8WWlkUfRPYkpjLpm+wn+1o=",
"expires_at": "2026-04-13T08:37:02Z"
},
"config_version": {
"before": 2,
"after": 3
}
}Note: The configuration version increments, but changes are not yet published.
Step 3: Sign and Publish
Sign the configuration and publish it to the CDN:
Cloud-Managed Keys:
trustpin-cli projects sign \
<organization-id> \
<project-id> \
--password <master-password>Bring Your Own Key (BYOK):
trustpin-cli projects sign \
<organization-id> \
<project-id> \
--private-key path/to/private-key.pemExample output:
[1/5] Getting project information
Project: Production API (Managed CDN with Cloud Keys)
[2/5] Loading project configuration
Configuration loaded with 3 domains
[3/5] Preparing private key
Using cloud-managed private key
[4/5] Creating and signing JWT
JWT signed successfully
[5/5] Uploading signed configuration
✅ Configuration published successfully!The signed configuration is now live and available to your mobile apps.
Complete Workflow Script
This script automates the entire process with error handling:
#!/bin/bash
set -e
ORG_ID="fb52418e-b5ae-4bff-b973-6da9ae07ba00"
PROJECT_ID="9caaea0a-013e-4e7b-80ea-cee6bfb52b36"
DOMAIN="api.example.com"
CERT_FILE="certs/api-cert.pem"
echo "═══ Step 1: Extract Pin from Certificate ═══"
SPKI_SHA256=$(openssl x509 -in "$CERT_FILE" -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64)
# Extract expiration date (portable across Linux/macOS)
EXPIRES_EPOCH=$(openssl x509 -in "$CERT_FILE" -noout -enddate | \
cut -d= -f2 | \
xargs -I{} date -jf "%b %d %H:%M:%S %Y %Z" "{}" +%s 2>/dev/null || \
date -d "$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)" +%s)
EXPIRES=$(date -u -r "$EXPIRES_EPOCH" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || \
date -u -d "@$EXPIRES_EPOCH" +%Y-%m-%dT%H:%M:%SZ)
echo " SPKI SHA-256: $SPKI_SHA256"
echo " Expires: $EXPIRES"
echo ""
echo "═══ Step 2: Upsert Certificate Pin ═══"
RESULT=$(trustpin-cli projects upsert "$ORG_ID" "$PROJECT_ID" \
--domain "$DOMAIN" \
--pin "spki-sha256:$SPKI_SHA256" \
--expires "$EXPIRES" \
--output json)
echo "$RESULT" | jq '.'
# Verify success
STATUS=$(echo "$RESULT" | jq -r '.status')
if [ "$STATUS" != "success" ]; then
echo "❌ Failed to upsert pin"
exit 1
fi
ACTION=$(echo "$RESULT" | jq -r '.action')
echo "✅ Pin ${ACTION} successfully"
echo ""
echo "═══ Step 3: Sign and Publish Configuration ═══"
trustpin-cli projects sign "$ORG_ID" "$PROJECT_ID" \
--password "$MASTER_PASSWORD"
echo ""
echo "✅ Certificate pin updated and published!"Advanced Use Cases
Verifying Published Configuration
After signing and publishing, verify the configuration is correctly deployed to the CDN:
# Verify JWS signature using public key from CDN
trustpin-cli projects jws $ORG_ID $PROJECT_ID --verify
# Decode and inspect published configuration
trustpin-cli projects jws $ORG_ID $PROJECT_ID --decode
# Save published JWS for archival/compliance
trustpin-cli projects jws $ORG_ID $PROJECT_ID \
--output-file "archive/config-$(date +%Y%m%d-%H%M%S).jws"Why validation matters:
- Confirms the
signcommand successfully published to CDN - Catches CDN propagation delays or failures
- Provides audit trail of published configurations
- Enables comparison between database and CDN state
Example validation script:
#!/bin/bash
set -e
ORG_ID="fb52418e-b5ae-4bff-b973-6da9ae07ba00"
PROJECT_ID="9caaea0a-013e-4e7b-80ea-cee6bfb52b36"
echo "Verifying published configuration..."
# Check if JWS is published
JWS=$(trustpin-cli projects jws $ORG_ID $PROJECT_ID 2>/dev/null)
if [ -z "$JWS" ]; then
echo "❌ No JWS published on CDN"
exit 1
fi
# Verify signature
if ! trustpin-cli projects jws $ORG_ID $PROJECT_ID --verify &>/dev/null; then
echo "❌ JWS signature verification failed"
exit 5
fi
echo "✅ JWS signature valid"
# Check version alignment
trustpin-cli projects jws $ORG_ID $PROJECT_ID --decode | grep -E "(Current DB Version|Published Version)"
echo "✅ Published configuration validated"Self-Hosted CDN Deployment
For organizations hosting JWS configurations on their own infrastructure:
Workflow:
- Use TrustPin to manage and sign configurations (upsert + sign)
- Download the signed JWS from TrustPin CDN
- Deploy to your own CDN/servers
- Configure mobile SDKs to fetch from your infrastructure
Deployment script:
#!/bin/bash
set -e
ORG_ID="fb52418e-b5ae-4bff-b973-6da9ae07ba00"
PROJECT_ID="9caaea0a-013e-4e7b-80ea-cee6bfb52b36"
CDN_PATH="/var/www/cdn/trustpin"
echo "═══ Step 1: Upsert Certificate Pins ═══"
# Update your pins...
trustpin-cli projects upsert $ORG_ID $PROJECT_ID \
--domain api.example.com \
--pin spki-sha256:$SPKI_SHA256 \
--expires $EXPIRES
echo ""
echo "═══ Step 2: Sign Configuration ═══"
trustpin-cli projects sign $ORG_ID $PROJECT_ID \
--password "$MASTER_PASSWORD"
echo ""
echo "═══ Step 3: Download Signed JWS ═══"
trustpin-cli projects jws $ORG_ID $PROJECT_ID \
--output-file "$CDN_PATH/config.jws"
echo ""
echo "═══ Step 4: Verify JWS Integrity ═══"
if ! trustpin-cli projects jws $ORG_ID $PROJECT_ID --verify; then
echo "❌ JWS verification failed - aborting deployment"
exit 5
fi
echo ""
echo "═══ Step 5: Deploy to CDN ═══"
# Example: Upload to S3, CloudFront, or your CDN
aws s3 cp "$CDN_PATH/config.jws" s3://your-bucket/trustpin/config.jws \
--cache-control "public, max-age=3600" \
--metadata "version=$(date +%s)"
# Invalidate CDN cache if needed
aws cloudfront create-invalidation \
--distribution-id YOUR_DISTRIBUTION_ID \
--paths "/trustpin/config.jws"
echo "✅ JWS deployed to self-hosted CDN"Benefits:
- Full control over CDN infrastructure and caching
- Compliance with data residency requirements
- Integration with existing CDN/monitoring systems
- Custom cache invalidation strategies
AWS ACM: Automated Certificate Pinning on Renewal
When AWS Certificate Manager (ACM) automatically renews a certificate, this workflow detects the renewal via EventBridge, extracts the new certificate’s pins, upserts them into TrustPin, and signs/publishes the configuration using a BYOK private key stored in AWS Secrets Manager.
Architecture
ACM Certificate Renewal
│
▼
EventBridge Rule ──▶ Lambda Function
(ACM Action event) │
├── 1. Get certificate from ACM (aws sdk)
├── 2. Extract SPKI pin (openssl)
├── 3. Upsert pin (trustpin-cli projects upsert)
├── 4. Fetch BYOK key from Secrets Manager
└── 5. Sign & publish (trustpin-cli projects sign --private-key)Prerequisites:
- ACM certificate with automatic renewal enabled
- TrustPin project configured with BYOK (Bring Your Own Key)
- BYOK private key stored in AWS Secrets Manager
- TrustPin API token stored in AWS Secrets Manager
SAM Template (template.yaml)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Automated TrustPin certificate pin updates on ACM certificate renewal.
Detects ACM renewals via EventBridge, extracts pins, and publishes
signed configuration using BYOK.
Parameters:
TrustPinOrgId:
Type: String
Description: TrustPin organization ID
TrustPinProjectId:
Type: String
Description: TrustPin project ID
AcmCertificateArn:
Type: String
Description: ARN of the ACM certificate to monitor
Domain:
Type: String
Description: Domain name associated with the certificate (e.g., api.example.com)
TrustPinApiTokenSecretArn:
Type: String
Description: ARN of the Secrets Manager secret containing the TrustPin API token
ByokPrivateKeySecretArn:
Type: String
Description: ARN of the Secrets Manager secret containing the BYOK private key (PEM)
Resources:
# EventBridge rule: triggers on ACM certificate renewal
AcmRenewalRule:
Type: AWS::Events::Rule
Properties:
Description: Triggers on ACM certificate renewal completion
EventPattern:
source:
- aws.acm
detail-type:
- "ACM Certificate Action"
detail:
ActionType:
- RENEWAL
CertificateArn:
- !Ref AcmCertificateArn
State: ENABLED
Targets:
- Id: TrustPinPinUpdater
Arn: !GetAtt PinUpdaterFunction.Arn
# Permission for EventBridge to invoke the Lambda
AcmRenewalPermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref PinUpdaterFunction
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt AcmRenewalRule.Arn
# Lambda function: updates TrustPin pins on renewal
PinUpdaterFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: trustpin-acm-pin-updater
Runtime: provided.al2023
Handler: bootstrap
Timeout: 120
MemorySize: 256
Architectures:
- x86_64
Environment:
Variables:
TRUSTPIN_ORG_ID: !Ref TrustPinOrgId
TRUSTPIN_PROJECT_ID: !Ref TrustPinProjectId
DOMAIN: !Ref Domain
ACM_CERTIFICATE_ARN: !Ref AcmCertificateArn
API_TOKEN_SECRET_ARN: !Ref TrustPinApiTokenSecretArn
BYOK_KEY_SECRET_ARN: !Ref ByokPrivateKeySecretArn
Policies:
- Version: '2012-10-17'
Statement:
# Read the ACM certificate
- Effect: Allow
Action:
- acm:GetCertificate
- acm:DescribeCertificate
Resource: !Ref AcmCertificateArn
# Read secrets (API token + BYOK private key)
- Effect: Allow
Action:
- secretsmanager:GetSecretValue
Resource:
- !Ref TrustPinApiTokenSecretArn
- !Ref ByokPrivateKeySecretArnLambda Handler Script (handler.sh)
The Lambda uses a custom runtime (provided.al2023) to run a shell script with the TrustPin CLI binary bundled in the deployment package.
#!/bin/bash
set -euo pipefail
# --- Custom Lambda Runtime Loop ---
# Polls the Lambda Runtime API for invocation events and processes them.
RUNTIME_API="http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime"
while true; do
# Get next event
HEADERS=$(mktemp)
EVENT=$(curl -sS -D "$HEADERS" "${RUNTIME_API}/invocation/next")
REQUEST_ID=$(grep -i "Lambda-Runtime-Aws-Request-Id" "$HEADERS" | tr -d '\r' | cut -d' ' -f2)
# Process the event
RESPONSE=$(process_event "$EVENT" 2>&1) && STATUS="success" || STATUS="error"
if [ "$STATUS" = "success" ]; then
curl -sS -X POST "${RUNTIME_API}/invocation/${REQUEST_ID}/response" \
-d "{\"status\": \"success\", \"message\": \"$RESPONSE\"}"
else
curl -sS -X POST "${RUNTIME_API}/invocation/${REQUEST_ID}/error" \
-d "{\"errorType\": \"PinUpdateError\", \"errorMessage\": \"$RESPONSE\"}"
fi
rm -f "$HEADERS"
done
process_event() {
local EVENT="$1"
local CERT_ARN="$ACM_CERTIFICATE_ARN"
echo "Processing ACM renewal for certificate: $CERT_ARN"
# Step 1: Retrieve TrustPin API token from Secrets Manager
export TRUSTPIN_API_TOKEN=$(aws secretsmanager get-secret-value \
--secret-id "$API_TOKEN_SECRET_ARN" \
--query 'SecretString' --output text)
# Step 2: Retrieve BYOK private key from Secrets Manager
PRIVATE_KEY_FILE=$(mktemp /tmp/byok-key-XXXXXX.pem)
aws secretsmanager get-secret-value \
--secret-id "$BYOK_KEY_SECRET_ARN" \
--query 'SecretString' --output text > "$PRIVATE_KEY_FILE"
chmod 600 "$PRIVATE_KEY_FILE"
# Step 3: Export the renewed certificate from ACM
CERT_FILE=$(mktemp /tmp/cert-XXXXXX.pem)
aws acm get-certificate \
--certificate-arn "$CERT_ARN" \
--query 'Certificate' --output text > "$CERT_FILE"
# Step 4: Extract SPKI SHA-256 pin and expiration from the certificate
SPKI_SHA256=$(openssl x509 -in "$CERT_FILE" -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | \
base64)
# Convert expiration to ISO 8601 format (portable across Linux/macOS)
EXPIRES_EPOCH=$(openssl x509 -in "$CERT_FILE" -noout -enddate | \
cut -d= -f2 | \
xargs -I{} date -jf "%b %d %H:%M:%S %Y %Z" "{}" +%s 2>/dev/null || \
date -d "$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)" +%s)
EXPIRES=$(date -u -r "$EXPIRES_EPOCH" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || \
date -u -d "@$EXPIRES_EPOCH" +%Y-%m-%dT%H:%M:%SZ)
echo "Extracted SPKI SHA-256: ${SPKI_SHA256:0:20}..."
echo "Certificate expires: $EXPIRES"
# Step 5: Upsert the pin into TrustPin
./trustpin-cli projects upsert \
"$TRUSTPIN_ORG_ID" "$TRUSTPIN_PROJECT_ID" \
--domain "$DOMAIN" \
--pin "spki-sha256:${SPKI_SHA256}" \
--expires "$EXPIRES" \
--output json
# Step 6: Sign and publish with BYOK private key
./trustpin-cli projects sign \
"$TRUSTPIN_ORG_ID" "$TRUSTPIN_PROJECT_ID" \
--private-key "$PRIVATE_KEY_FILE"
# Cleanup sensitive files
rm -f "$PRIVATE_KEY_FILE" "$CERT_FILE"
echo "Pin updated and configuration published for $DOMAIN"
}Deployment
# 1. Create the deployment package
mkdir -p build
cp handler.sh build/bootstrap
chmod +x build/bootstrap
# Download the TrustPin CLI Linux binary into the package
curl -L https://github.com/trustpin-cloud/homebrew-trustpin/releases/latest/download/trustpin-cli-linux-x64 \
-o build/trustpin-cli
chmod +x build/trustpin-cli
cd build && zip -r ../function.zip . && cd ..
# 2. Store secrets in AWS Secrets Manager
aws secretsmanager create-secret \
--name trustpin/api-token \
--secret-string "tp_your_token_here"
aws secretsmanager create-secret \
--name trustpin/byok-private-key \
--secret-string file://private-key.pem
# 3. Deploy with SAM
sam deploy \
--template-file template.yaml \
--stack-name trustpin-acm-auto-pin \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
TrustPinOrgId=fb52418e-b5ae-4bff-b973-6da9ae07ba00 \
TrustPinProjectId=9caaea0a-013e-4e7b-80ea-cee6bfb52b36 \
AcmCertificateArn=arn:aws:acm:us-east-1:123456789012:certificate/abc-def-123 \
Domain=api.example.com \
TrustPinApiTokenSecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:trustpin/api-token-AbCdEf \
ByokPrivateKeySecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:trustpin/byok-private-key-GhIjKl
# 4. Test with a manual invocation
aws lambda invoke \
--function-name trustpin-acm-pin-updater \
--payload '{"detail":{"ActionType":"RENEWAL"}}' \
response.json && cat response.jsonWhat happens on ACM renewal:
- ACM renews the certificate (automatic, managed by AWS)
- EventBridge detects the
ACM Certificate Actionevent withActionType: RENEWAL - Lambda is invoked automatically
- Lambda exports the renewed certificate from ACM via the AWS SDK
- Extracts the SPKI SHA-256 pin and expiration using
openssl - Upserts the pin into TrustPin with
trustpin-cli projects upsert - Signs and publishes the configuration using the BYOK private key with
trustpin-cli projects sign --private-key - Mobile apps fetch the updated configuration from the CDN on their next refresh
Critical considerations:
⚠️ ACM Key Rotation: ACM generates new key pairs on every renewal (key reuse is not supported). This means the SPKI pin will change on every renewal. To prevent mobile app pinning failures:
- Maintain dual pins: Keep both old and new certificate pins active during the transition period
- Monitor app refresh cycles: Ensure sufficient overlap time for all active app instances to fetch the new configuration
- Set appropriate overlap windows:
- Recommended: 7-14 days overlap between old and new pins for mobile apps
- Minimum: Consider your app’s usage patterns—if users don’t open the app for weeks, a longer overlap is critical
- Automated environments: For server-to-server or CI/CD deployments with guaranteed refresh cycles, shorter overlaps (hours to days) may be acceptable
Recommended dual-pin strategy:
# Before renewal (old cert expires in 30 days)
# Old pin: expires 2026-03-01
# Status: Active
# After renewal detected (new cert issued)
# Old pin: expires 2026-03-01 (keep active)
# New pin: expires 2027-03-01 (newly added)
# Status: Both active for 30 days
# After old cert expires (2026-03-01)
# New pin: expires 2027-03-01
# Status: Old pin automatically ignored by SDKsThis ensures zero downtime during certificate renewals and accounts for mobile apps that haven’t fetched the updated configuration yet.
Troubleshooting
Authentication Issues
Problem: HTTP 401 Unauthorized
Solutions:
# Verify token is set correctly
echo $TRUSTPIN_API_TOKEN
# Test authentication
trustpin-cli projects list --output json
# Reconfigure CLI
trustpin-cli configureIn CI/CD:
- Verify
TRUSTPIN_API_TOKENsecret is set correctly - Ensure token hasn’t expired (create new token if needed)
- Check token has access to the organization/project
Validation Errors
Problem: Invalid pin format or type
❌ Validation failed: invalid pin type: sha255
Valid types: sha256, sha512, spki-sha256, spki-sha512Solution: Fix typo in pin type (e.g., sha255 → sha256)
Problem: Invalid base64 encoding
❌ Validation failed: invalid base64 encoding in pin valueSolution: Ensure hash is base64-encoded, not hex:
# Correct: base64 encoding
openssl dgst -sha256 -binary | base64
# Incorrect: hex encoding
openssl dgst -sha256Problem: Wrong hash length
❌ Validation failed: invalid sha256 hash length: expected 32 bytes, got 16 bytesSolution: Verify you’re hashing the correct data:
# For SPKI pins (correct)
openssl x509 -in cert.pem -pubkey -noout | \
openssl pkey -pubin -outform der | \
openssl dgst -sha256 -binary | base64
# For certificate pins (correct)
openssl x509 -in cert.pem -outform der | \
openssl dgst -sha256 -binary | base64Private Key Issues (BYOK)
Problem: Failed to decrypt private key
❌ Failed to decrypt private key: cipher: message authentication failedSolutions:
- Verify master password is correct for cloud-managed keys
- Verify private key password is correct for BYOK
- Check private key file is in PEM format:
file private-key.pem
Problem: Private key format errors in CI/CD
# Verify key is properly decoded
file private-key.pem
# Should show: "PEM RSA private key" or similar
# Check file permissions
ls -la private-key.pem
# Should be 600 or 400Network Issues
Problem: Connection timeout or network errors
Solutions:
# Test API connectivity
curl -H "Authorization: Bearer $TRUSTPIN_API_TOKEN" \
https://api.trustpin.cloud/users
# Check API base URL
echo $TRUSTPIN_API_BASE_URL
# Use verbose mode for debugging
trustpin-cli projects sign <org-id> <project-id> --verboseUpsert Operation Issues
Problem: Upsert succeeds but nothing changes
Reason: The pin already exists with the same expiration (idempotent operation)
Response:
{
"status": "success",
"operation": "upsert",
"action": "no_change",
"message": "Pin already exists with same expiration"
}Solution: This is expected behavior. No action needed.
Exit Codes
The CLI uses standard exit codes for automation:
| Code | Meaning | Example |
|---|---|---|
| 0 | Success or no-op | Pin added/updated, or already exists |
| 2 | API error | 401, 404, 500 HTTP errors |
| 4 | Validation error | Invalid domain, pin format, or type |
| 99 | Unexpected error | Network timeout, file I/O error |
Use in scripts:
if ! trustpin-cli projects upsert ... --output json > result.json; then
EXIT_CODE=$?
echo "❌ Upsert failed with exit code $EXIT_CODE"
cat result.json
exit $EXIT_CODE
fiGetting Help
View command help:
trustpin-cli --help
trustpin-cli projects --help
trustpin-cli projects upsert --help
trustpin-cli projects sign --helpEnable verbose output:
trustpin-cli projects upsert ... --verbose
trustpin-cli projects sign ... --verboseCheck CLI version:
trustpin-cli --versionFor additional support, contact support@trustpin.cloud or visit the TrustPin Console .