Do not trust the claims from an unverified JWS in a security context. For analysis, it’s fine. For access control, always verify the signature. Real-World Example Input ( tokens.txt ):
"user": "id": 123, "name": "Alice", "permissions": ["read", "write"]
Extend the script to handle JWE (encrypted tokens) or add signature validation columns. Happy data wrangling. Have you built a similar converter for a different token format? Let me know in the comments. jws to csv converter
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoidXNlciIsImV4cCI6MTczNTY4OTAwMH0.signature1 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0NTYiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MzU2ODkwMDB9.signature2 python jws_to_csv.py tokens.txt output.csv --fields sub,role
from pandas import json_normalize normalized = json_normalize(payload) rows.append(normalized.iloc[0].to_dict()) What About Invalid or Expired Signatures? A pure converter doesn’t need to verify the signature – it just decodes the payload. However, you may want to add a signature_valid column using a cryptographic library (e.g., cryptography or jwt with verification disabled first, then verified separately). Do not trust the claims from an unverified
def jws_to_csv(input_file, output_file, fields_of_interest=None): """ Convert a file of JWS tokens (one per line) to CSV. fields_of_interest: list of claim names to extract (e.g., ['sub', 'exp', 'role']) """ tokens = Path(input_file).read_text().splitlines() rows = []
In this post, I’ll walk through why you’d want a JWS-to-CSV converter, the structure of a JWS, and a simple Python script to get the job done. A JSON Web Signature (JWS) is a way to securely transmit JSON data between parties with a signature. It’s the technical backbone of JWT (when signed). A JWS has three parts, each base64url-encoded, separated by dots: Real-World Example Input ( tokens
If you work with JWT (JSON Web Tokens) or JWS (JSON Web Signatures) in logging, analytics, or batch processing, you’ve likely run into the same headache: how do you analyze hundreds or thousands of these tokens in a human-readable way?
for token in tokens: if not token.strip(): continue payload = decode_jws_payload(token) # If no fields specified, take all top-level keys if fields_of_interest is None: rows.append(payload) else: filtered = field: payload.get(field, None) for field in fields_of_interest rows.append(filtered)
To flatten these into CSV columns (e.g., user.id , permissions.0 ), you can use pandas.json_normalize() instead of the direct DataFrame constructor.
df = pd.DataFrame(rows) df.to_csv(output_file, index=False) print(f"✅ Converted len(rows) tokens to output_file") if == " main ": # Example usage jws_to_csv("tokens.txt", "output.csv", fields_of_interest=["sub", "exp", "tenant_id"]) Step 3: Handling nested claims Sometimes your JWS payload contains nested objects: