π·πΊ Π ΡΡΡΠΊΠΈΠΉ | πΊπΈ English
A production-ready JWT (JSON Web Token) parser with three implementations:
- Pure Bash - Zero dependencies (works with only
base64) - Pure Go - Full JWT algorithm support (HMAC, RSA, ECDSA)
- Hybrid Router - Intelligent routing between Bash and Go
Designed for restricted environments: Works in closed banking networks, minimal Alpine images, and Astra Linux SE without jq/openssl.
Version: 1.0.0 License: MIT
Production-grade JWT parser designed for restricted banking environments with minimal dependencies. Supports three deployment modes:
- Pure Bash - Works anywhere with
base64(optional:jq,openssl) - Pure Go - Statically compiled, zero dependencies
- Hybrid - Intelligent routing between Bash and Go for optimal performance
β Minimal Dependencies
- Bash version: Only requires
base64(built-in on all Linux) - Go version: Statically compiled, zero runtime dependencies
- Works in Alpine, Astra Linux SE, Ubuntu, and any modern Linux
β Full JWT Support
- Parse header, payload, signature
- Validate standard claims (
exp,nbf,iat,sub,iss,aud) - Detect expired tokens, not-yet-valid tokens
- Human-readable and JSON output formats
β Signature Verification
- HMAC algorithms: HS256, HS384, HS512 (bash + openssl or Go)
- RSA algorithms: RS256, RS384, RS512 (Go only)
- ECDSA algorithms: ES256, ES384, ES512 (Go only)
β Banking Security
- Exit codes for automation
- Detailed validation errors
- Audit-friendly logging
- No external network dependencies
# Clone or copy to your system
cd /opt/jwt-parser
# Build Go binaries (optional, if not pre-built)
make build-all
# Make scripts executable
chmod +x jwt-parser.sh jwt-parser-hybrid.sh
# Test with sample token
./jwt-parser.sh "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"# Parse JWT token
./jwt-parser.sh "YOUR_JWT_TOKEN_HERE"
# Verify signature (HMAC)
./jwt-parser.sh --secret "your-secret-key" "YOUR_JWT_TOKEN_HERE"
# JSON output for automation
./jwt-parser.sh --json "YOUR_JWT_TOKEN_HERE" | jq .
# Use hybrid mode (auto-routing)
./jwt-parser-hybrid.sh --secret "your-secret-key" "YOUR_JWT_TOKEN_HERE"
# Use Go version (full algorithm support)
./jwt-parser -secret "your-secret-key" "YOUR_JWT_TOKEN_HERE"/opt/jwt-parser/
βββ jwt-parser.sh # Bash implementation (auto-detect tools)
βββ jwt-parser-hybrid.sh # Hybrid orchestrator (Bash + Go)
βββ jwt-parser.go # Go source code
βββ jwt-parser # Go binary (current platform)
βββ jwt-parser-static # Go binary (static, no CGO)
βββ jwt-parser-alpine # Go binary (Alpine Linux)
βββ jwt-parser-astra # Go binary (Astra Linux)
βββ go.mod # Go dependencies
βββ Makefile # Build automation
βββ README.md # This file
βββ examples/ # Usage examples (see below)
Environment: Astra Linux SE, no internet, minimal packages
Solution: Use jwt-parser.sh (pure bash)
# Check what tools are available
./jwt-parser.sh --help
# Parse token (works without jq or openssl)
./jwt-parser.sh "YOUR_TOKEN"
# Output shows:
# - base64: β
# - jq: β (using pure bash JSON parser)
# - openssl/libre: β (signature verification disabled)Capabilities:
- β Decode header/payload
- β Validate claims (exp, nbf, iat)
- β Signature verification (no openssl)
Environment: Docker Alpine, need signature verification
Solution: Use jwt-parser-alpine (statically compiled Go)
# Copy binary to container
COPY jwt-parser-alpine /usr/local/bin/jwt-parser
# Use in application
jwt-parser -secret "$JWT_SECRET" "$TOKEN" || {
echo "Invalid token"
exit 1
}Capabilities:
- β Full signature verification
- β All algorithms (HS256, RS256, ES256, etc.)
- β Zero dependencies (3.1 MB binary)
Environment: Mixed (some servers have openssl, some don't)
Solution: Use jwt-parser-hybrid.sh (auto-routing)
# Hybrid script automatically chooses:
# - Bash if no signature verification needed (fastest)
# - Bash if HMAC + openssl available (native)
# - Go if RSA/ECDSA algorithms (required)
# - Go if signature needed but no openssl (fallback)
./jwt-parser-hybrid.sh --verbose --secret "$SECRET" "$TOKEN"
# Output shows routing decision:
# === Routing Decision ===
# Algorithm: HS256
# Signature verification: YES
# OpenSSL available: YES
# Selected parser: BASH
# Reason: HMAC algorithm + openssl available (bash can handle)Problem: Need to periodically check if tokens are valid in closed network
Solution:
#!/bin/bash
# /opt/scripts/check-auth.sh
TOKEN="$1"
LOG_FILE="/var/log/auth-diagnostics.log"
# Parse token
RESULT=$(./jwt-parser.sh --json "$TOKEN")
STATUS=$(echo "$RESULT" | jq -r '.validation_status')
# Log result
echo "[$(date)] Token validation: $STATUS" >> "$LOG_FILE"
# Alert on failure
if [[ "$STATUS" != "VALID" ]]; then
echo "$RESULT" | jq . >> "$LOG_FILE"
# Send alert (internal system)
alert-service --severity HIGH "Token validation failed: $STATUS"
fi
# Exit with appropriate code
case "$STATUS" in
"VALID") exit 0 ;;
"EXPIRED") exit 3 ;;
"NOT_YET_VALID") exit 4 ;;
"SIGNATURE_INVALID") exit 5 ;;
*) exit 2 ;;
esacProblem: Microservice needs to validate incoming JWT tokens
Solution (Docker):
FROM alpine:3.18
# Copy statically compiled parser
COPY jwt-parser-alpine /usr/local/bin/jwt-parser
# Your application
COPY app /app/
# Validation script
COPY validate-token.sh /app/
ENTRYPOINT ["/app/start.sh"]#!/bin/sh
# /app/validate-token.sh
TOKEN="$1"
# Validate with secret from environment
if jwt-parser -secret-env JWT_SECRET -json "$TOKEN" > /tmp/token.json; then
# Token valid - extract claims
USER_ID=$(jq -r '.claims.sub' /tmp/token.json)
ROLES=$(jq -r '.claims.roles[]' /tmp/token.json)
echo "Authenticated: User $USER_ID with roles $ROLES"
exit 0
else
echo "Authentication failed"
exit 1
fiProblem: Need to log all token usage for compliance
Solution:
#!/bin/bash
# /opt/scripts/audit-token.sh
TOKEN="$1"
AUDIT_LOG="/var/log/token-audit.log"
# Parse token and extract claims
RESULT=$(./jwt-parser.sh --json "$TOKEN")
# Create audit entry
AUDIT_ENTRY=$(jq -n \
--arg timestamp "$(date -Iseconds)" \
--arg user "$(echo "$RESULT" | jq -r '.claims.sub')" \
--arg issuer "$(echo "$RESULT" | jq -r '.claims.iss')" \
--arg status "$(echo "$RESULT" | jq -r '.validation_status')" \
'{
timestamp: $timestamp,
user: $user,
issuer: $issuer,
status: $status,
source_ip: env.REMOTE_ADDR
}')
# Append to audit log
echo "$AUDIT_ENTRY" >> "$AUDIT_LOG"
# Also send to SIEM (if available)
if command -v siem-client >/dev/null; then
echo "$AUDIT_ENTRY" | siem-client --category jwt_validation
fiUse exit codes for automation and monitoring:
| Code | Meaning | Action |
|---|---|---|
| 0 | Success (token valid) | Proceed |
| 1 | Invalid arguments | Fix command |
| 2 | Invalid JWT format | Reject token |
| 3 | Token expired | Request new token |
| 4 | Token not yet valid | Wait or reject |
| 5 | Signature invalid | Reject token (security!) |
| 6 | Required tools missing | Install dependencies |
Example:
if ./jwt-parser.sh --secret "$SECRET" "$TOKEN"; then
echo "Token valid - proceed"
else
EXIT_CODE=$?
case $EXIT_CODE in
3) echo "Token expired - request renewal" ;;
5) echo "SECURITY ALERT: Invalid signature!" ;;
*) echo "Token validation failed (code: $EXIT_CODE)" ;;
esac
exit 1
fi| Operation | Bash | Go | Notes |
|---|---|---|---|
| Parse only | ~10ms | ~5ms | Bash faster startup |
| Parse + verify (HS256) | ~15ms | ~8ms | Both fast enough |
| Parse + verify (RS256) | N/A | ~12ms | Go required |
| Memory usage | ~2 MB | ~5 MB | Both minimal |
| Binary size | 15 KB | 3.1 MB | Bash script tiny |
Recommendation: Use hybrid mode for optimal performance.
-
Always verify signatures in production
# Good ./jwt-parser.sh --secret "$SECRET" "$TOKEN" # Bad (dev only) ./jwt-parser.sh "$TOKEN" # No signature check!
-
Protect secrets
# Good - use environment variables export JWT_SECRET="your-secret" ./jwt-parser -secret-env JWT_SECRET "$TOKEN" # Bad - secret in command line (visible in ps) ./jwt-parser -secret "your-secret" "$TOKEN"
-
Validate claims
# Check validation status RESULT=$(./jwt-parser.sh --json "$TOKEN") if [[ "$(echo "$RESULT" | jq -r '.validation_status')" != "VALID" ]]; then echo "Reject token" exit 1 fi
-
Use HTTPS for token transmission
- Never send tokens over unencrypted HTTP
- Use TLS 1.2+ for all API calls
-
Rotate secrets regularly
- Change HMAC secrets every 90 days
- Use different secrets per environment
-
Bash JSON parser (when jq unavailable)
- Simple regex-based parsing
- May fail on complex nested JSON
- Solution: Install jq or use Go version
-
Pure bash mode (no openssl)
- Cannot verify signatures
- Claims validation only
- Solution: Use Go version or install openssl
-
Algorithm support (bash)
- HMAC only (HS256/384/512)
- No RSA/ECDSA support
- Solution: Use Go version for RSA/ECDSA
Solution: Install coreutils
# Alpine
apk add coreutils
# Astra/Debian
apt-get install coreutils
# RHEL/CentOS
yum install coreutilsCause: No openssl/libressl available
Solution:
# Option 1: Install openssl
apk add openssl # Alpine
apt-get install openssl # Debian/Astra
# Option 2: Use Go version
./jwt-parser -secret "$SECRET" "$TOKEN"Cause: Token corrupted or truncated
Solution:
# Check token has 3 parts
echo "$TOKEN" | tr '.' '\n' | wc -l
# Should output: 3
# Check each part is valid base64url
echo "$TOKEN" | cut -d. -f1 | base64 -dCause: Wrong architecture
Solution:
# Check your architecture
uname -m
# Rebuild for your platform
make build-static # Creates jwt-parser-static
# Or specify architecture
GOARCH=arm64 make build-static # For ARM servers- Bash 4.0+
- Go 1.21+ (for Go version)
- make (for build automation)
# Build all versions
make build-all
# Build specific versions
make build # Current platform
make build-static # Static (no CGO)
make build-alpine # Alpine Linux
make build-astra # Astra Linux
# Install system-wide
sudo make install # Copies to /usr/local/binEdit jwt-parser.sh or jwt-parser.go to:
- Add custom claim validation
- Change output formats
- Add logging/monitoring hooks
# Generate test token
./generate-test-token.sh
# Test bash version
./jwt-parser.sh --secret "test-secret" "$(cat test-token.txt)"
# Test Go version
./jwt-parser -secret "test-secret" "$(cat test-token.txt)"
# Test hybrid mode
./jwt-parser-hybrid.sh --verbose --secret "test-secret" "$(cat test-token.txt)"
# Test all exit codes
./test-all-scenarios.shFor issues or questions:
- Internal: Contact Security Engineering Team
- Bugs: Log in internal issue tracker
- Enhancements: Submit feature request
Internal Use Only - Proprietary software for banking operations.
Unauthorized distribution or use outside authorized systems is prohibited.
- Initial release
- Bash parser with auto-detection
- Go parser with full algorithm support
- Hybrid orchestrator
- Banking use case examples
- Complete documentation
End of Documentation