The Microsoft's Signing Transparency (MST) plugin provides integration with Microsoft's Signing Transparency service for registering and verifying COSE Sign1 signatures. This plugin demonstrates advanced authentication patterns and service integration capabilities.
Learn More: Read the announcement blog post for more information about Microsoft's Signing Transparency.
The MST plugin (CoseSignTool.MST.Plugin) extends CoseSignTool with commands to interact with Microsoft's Signing Transparency service:
mst_register- Register a COSE Sign1 signature with MSTmst_verify- Verify a COSE Sign1 signature against MST
The MST plugin is automatically included with CoseSignTool releases using the enhanced subdirectory architecture for dependency isolation. No additional installation is required.
Plugin Location: The plugin is deployed to plugins/CoseSignTool.MST.Plugin/ with all its Azure dependencies isolated in the subdirectory, preventing conflicts with other plugins or the main application.
The plugin supports flexible authentication methods with automatic fallback:
Set an access token in an environment variable:
# Using the default environment variable
export MST_TOKEN="your-access-token"
# Using a custom environment variable
export MY_MST_TOKEN="your-access-token"When no token is provided, the plugin automatically falls back to Azure DefaultCredential, which supports:
- Azure CLI credentials (
az login) - Managed Identity (in Azure environments)
- Azure PowerShell credentials
- Environment variables (
AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_TENANT_ID) - Visual Studio credentials
- VS Code credentials
⚠️ Production Security Note: When deploying to production environments, create an environment variable namedAZURE_TOKEN_CREDENTIALSand set its value to"prod". This excludes developer tool credentials from the credential chain, ensuring only production-appropriate credentials are used. This is required when using Azure.Identity version 1.14.0 or later. For more information, see the DefaultAzureCredential overview.
# In production environments, set this environment variable:
export AZURE_TOKEN_CREDENTIALS="prod"Register a COSE Sign1 signature with Microsoft's Signing Transparency service.
CoseSignTool mst_register [OPTIONS]--endpoint- Azure CTS service endpoint URL--payload- Path to the payload file--signature- Path to the COSE Sign1 signature file
--token-env-var- Environment variable name containing the access token (default:MST_TOKEN)--output- Output file path for the registration result--timeout- Operation timeout in seconds (default: 30)
Using default environment variable:
export MST_TOKEN="your-access-token"
CoseSignTool mst_register \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.coseUsing custom environment variable:
export MY_MST_TOKEN="your-access-token"
CoseSignTool mst_register \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--token-env-var MY_MST_TOKENUsing Azure DefaultCredential:
# Requires az login or other Azure authentication
CoseSignTool mst_register \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.coseWith output file:
export MST_TOKEN="your-access-token"
CoseSignTool mst_register \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--output registration-result.jsonVerify a COSE Sign1 signature against Microsoft's Signing Transparency service.
CoseSignTool mst_verify [OPTIONS]--endpoint- Azure CTS service endpoint URL--payload- Path to the payload file--signature- Path to the COSE Sign1 signature file
--token-env-var- Environment variable name containing the access token (default:MST_TOKEN)--output- Output file path for the verification result--receipt- Path to a specific receipt file to use for verification--timeout- Operation timeout in seconds (default: 30)--authorized-domains- Comma-separated list of authorized issuer domains for receipt verification--authorized-receipt-behavior- Behavior for receipts from authorized domains:VerifyAnyMatching- At least one receipt from any authorized domain must be validVerifyAllMatching- All receipts from authorized domains must be valid (default)RequireAll- There must be at least one valid receipt for each authorized domain
--unauthorized-receipt-behavior- Behavior for receipts from unauthorized domains:VerifyAll- Verify all receipts regardless of issuer domainIgnoreAll- Skip verification of receipts from unauthorized domainsFailIfPresent- Fail verification if any unauthorized receipt is present (default)
Universal Logging Options (available for all plugin commands):
--verbose,-v- Enable verbose logging output (detailed diagnostic information)--quiet,-q- Suppress all non-error output
Basic verification:
export MST_TOKEN="your-access-token"
CoseSignTool mst_verify \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.coseWith receipt output:
export MST_TOKEN="your-access-token"
CoseSignTool mst_verify \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--receipt transparency-receipt.coseWith authorized domain verification:
export MST_TOKEN="your-access-token"
CoseSignTool mst_verify \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--authorized-domains example.com,trusted.azure.com \
--authorized-receipt-behavior RequireAllWith custom receipt behaviors:
export MST_TOKEN="your-access-token"
CoseSignTool mst_verify \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--authorized-domains mycompany.com \
--authorized-receipt-behavior VerifyAnyMatching \
--unauthorized-receipt-behavior IgnoreAllWith verbose logging:
export MST_TOKEN="your-access-token"
CoseSignTool mst_verify \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--verboseWith quiet mode (errors only):
export MST_TOKEN="your-access-token"
CoseSignTool mst_verify \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose \
--quietname: Sign and Register with MST
on:
push:
branches: [ main ]
jobs:
sign-and-register:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Install CoseSignTool
run: |
curl -L https://github.com/microsoft/CoseSignTool/releases/latest/download/CoseSignTool-Linux-release.zip -o CoseSignTool.zip
unzip CoseSignTool.zip
chmod +x CoseSignTool
- name: Sign file
run: |
./CoseSignTool sign \
--payload myfile.txt \
--p12-file ${{ secrets.SIGNING_CERT_P12 }} \
--p12-password ${{ secrets.SIGNING_CERT_PASSWORD }} \
--output myfile.txt.cose
- name: Register with MST
env:
MST_TOKEN: ${{ secrets.MST_TOKEN }}
AZURE_TOKEN_CREDENTIALS: "prod" # Exclude developer credentials in production
run: |
./CoseSignTool mst_register \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cosetrigger:
- main
pool:
vmImage: ubuntu-latest
variables:
MST_TOKEN: $(azure-cts-token) # Set in Azure DevOps Library
AZURE_TOKEN_CREDENTIALS: "prod" # Exclude developer credentials in production
steps:
- task: UseDotNet@2
displayName: 'Use .NET 8.0'
inputs:
packageType: 'sdk'
version: '8.0.x'
- bash: |
curl -L https://github.com/microsoft/CoseSignTool/releases/latest/download/CoseSignTool-Linux-release.zip -o CoseSignTool.zip
unzip CoseSignTool.zip
chmod +x CoseSignTool
displayName: 'Install CoseSignTool'
- bash: |
./CoseSignTool sign \
--payload myfile.txt \
--p12-file $(signing-cert-p12) \
--p12-password $(signing-cert-password) \
--output myfile.txt.cose
displayName: 'Sign file'
- bash: |
./CoseSignTool mst_register \
--endpoint https://your-mst-instance.azure.com \
--payload myfile.txt \
--signature myfile.txt.cose
displayName: 'Register with MST'The MST plugin provides three logging levels to help diagnose issues:
Shows operation status and results:
CoseSignTool mst_verify --endpoint https://... --payload file.txt --signature file.txt.cose
# Output:
# Verifying COSE Sign1 message with MST...
# Verification result: VALIDShows detailed diagnostic information including:
- Endpoint and file paths
- Verification options being used
- Authorized/unauthorized domains
- Receipt processing steps
- Message sizes and entry IDs
- Detailed exception information including stack traces
CoseSignTool mst_verify --endpoint https://... --payload file.txt --signature file.txt.cose --verbose
# Output:
# [VERBOSE] Starting MST operation
# [VERBOSE] Endpoint: https://...
# [VERBOSE] Starting transparency verification
# [VERBOSE] Transparency header found in message
# [VERBOSE] Authorized domains: example.com
# [VERBOSE] Calling CodeTransparencyClient.VerifyTransparentStatement
# [VERBOSE] Transparency verification succeeded
# Verifying COSE Sign1 message with MST...
# Verification result: VALIDWhen to use verbose mode:
- Diagnosing verification failures
- Understanding which verification options are active
- Troubleshooting receipt issues
- Reporting bugs with detailed context
Suppresses all output except errors:
CoseSignTool mst_verify --endpoint https://... --payload file.txt --signature file.txt.cose --quiet
# Only errors are shown, ideal for scripting and automationWhen to use quiet mode:
- CI/CD pipelines where only failures matter
- Automated scripts that check exit codes
- Batch processing scenarios
- When logging to files and console output is unnecessary
The mst_verify command supports advanced verification options to control how receipts from different issuer domains are validated:
Specify a list of trusted issuer domains using --authorized-domains. This is useful when you want to:
- Enforce that receipts come from specific, trusted MST instances
- Validate multi-tenant scenarios where different domains may issue receipts
- Implement security policies requiring specific issuer verification
Example:
--authorized-domains company.azure.com,partner.azure.comAuthorized Receipt Behavior (--authorized-receipt-behavior):
- VerifyAnyMatching: At least one receipt from any authorized domain must pass verification. Use this for flexibility when multiple trusted sources exist, but only one needs to validate successfully.
- VerifyAllMatching (default): All receipts from authorized domains must pass verification. Use this when you require all trusted sources to validate successfully.
- RequireAll: There must be at least one valid receipt for each authorized domain. Use this when you require coverage from every specified trusted source.
Unauthorized Receipt Behavior (--unauthorized-receipt-behavior):
- VerifyAll: Verify all receipts regardless of issuer domain. Use this for maximum validation coverage.
- IgnoreAll: Skip verification of receipts from unauthorized domains. Use this when you only care about specific trusted sources.
- FailIfPresent (default): Fail verification if any unauthorized receipt is present. Use this for strict security policies that don't allow unknown issuers.
Scenario 1: Require specific trusted domain
CoseSignTool mst_verify \
--endpoint https://your-mst.azure.com \
--payload file.txt \
--signature file.txt.cose \
--authorized-domains your-mst.azure.com \
--authorized-receipt-behavior RequireAll \
--unauthorized-receipt-behavior FailIfPresentScenario 2: Accept any of multiple trusted sources
CoseSignTool mst_verify \
--endpoint https://your-mst.azure.com \
--payload file.txt \
--signature file.txt.cose \
--authorized-domains primary.azure.com,backup.azure.com \
--authorized-receipt-behavior VerifyAnyMatching \
--unauthorized-receipt-behavior IgnoreAllScenario 3: Require all trusted domains with no unauthorized receipts
CoseSignTool mst_verify \
--endpoint https://your-mst.azure.com \
--payload file.txt \
--signature file.txt.cose \
--authorized-domains primary.azure.com,secondary.azure.com \
--authorized-receipt-behavior RequireAll \
--unauthorized-receipt-behavior FailIfPresent- Never hardcode tokens - Always use environment variables or Azure credentials
- Use secure secret management - Store tokens in Azure Key Vault, GitHub Secrets, or Azure DevOps Library
- Rotate tokens regularly - Implement token rotation policies
- Use managed identities - When running in Azure, prefer managed identities over access tokens
- Production DefaultAzureCredential configuration - In production environments, set
AZURE_TOKEN_CREDENTIALS="prod"to exclude developer tool credentials from the credential chain. This is required when using Azure.Identity version 1.14.0 or later for security compliance.
- Set appropriate timeouts - Use
--timeoutfor long-running operations - Batch operations - When possible, batch multiple operations to reduce authentication overhead
- Monitor usage - Track API calls and response times for capacity planning
The plugin returns specific exit codes for different scenarios:
0- Success1- Generic error2- Missing required option3- Invalid argument value4- User-specified file not found5- Authentication failed6- Network/service error
Authentication Failed:
Error: Azure.Identity.CredentialUnavailableException: DefaultAzureCredential failed to retrieve a token
- Ensure
MST_TOKENis set, or authenticate with Azure CLI (az login) - Check that the token has appropriate permissions for the CTS service
Connection Timeout:
Error: The operation timed out after 30 seconds
- Increase timeout with
--timeout 60 - Check network connectivity to the MST endpoint
Invalid Endpoint:
Error: The endpoint URL is not valid
- Verify the endpoint URL format:
https://your-mst-instance.azure.com - Ensure the MST service is accessible from your network
Production Authentication Issues:
Error: DefaultAzureCredential used developer credentials in production
- Set
AZURE_TOKEN_CREDENTIALS="prod"to exclude developer tool credentials - Ensure proper production authentication is configured (managed identity, service principal, etc.)
- Review authentication chain in logs to verify correct credential type is used
Enable verbose logging by setting environment variable:
export AZURE_CORE_DIAGNOSTICS_LOGGING_ENABLED=trueThe MST plugin is built using:
- CoseSignTool.Abstractions - Base plugin interfaces
- Azure.Identity - Azure authentication library
- Azure.Core - Azure SDK core functionality
- System.Text.Json - JSON serialization
The plugin source code is available in the CoseSignTool repository:
CoseSignTool.MST.Plugin/
├── MstPlugin.cs # Main plugin class
├── MstCommandBase.cs # Base command functionality
├── RegisterCommand.cs # Register command implementation
├── VerifyCommand.cs # Verify command implementation
├── CodeTransparencyClientHelper.cs # Authentication helper
└── CoseSignTool.MST.Plugin.csproj
To contribute to the MST plugin:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Update documentation
- Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
For issues and questions:
- Plugin Issues: GitHub Issues
- MST Service: Azure support channels
- Documentation: CoseSignTool Documentation
This plugin is licensed under the MIT License. See LICENSE for details.