Secure Encrypted Token Workflow in CKAN-2.10.4(Email and Admin level Validation)
While building a secure access request system in CKAN for internal datasets, I faced a key challenge:
Secure Encrypted Token Workflow in CKAN-2.10.4(Email and Admin level Validation)

While building a secure access request system in CKAN for internal datasets, I faced a key challenge:
How do we let users request access securely and validate them via email, without exposing raw tokens or relying on basic UUIDs?
- I needed a system that generated one-time, time-bound, tamper-proof tokens for each access request.
- Instead of using Fernet or JWT, I implemented a lightweight but secure solution using
hashlib,base64, and a shared secret.
This post walks through that token generation and validation process.
Why Use Encrypted Tokens (Instead of Raw UUIDs)?
- Raw UUIDs are guessable if exposed in patterns.
- They can be tampered with if not verified properly.
- Encryption ensures:
- The token is unreadable and URL-safe
- No one can forge a valid token without the secret
- We can expire it on the server without storing sessions
Step 1: Token Generation with hashlib + base64
import hashlib
import base64
import uuid
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
def generate_token():
raw_token = str(uuid.uuid4())
hash_object = hashlib.sha256((raw_token + SECRET_KEY).encode())
token = base64.urlsafe_b64encode(hash_object.digest()).decode()
return token, raw_token
We generate a raw_token using UUID and encrypt it by hashing it with a secret key. The hash is then base64-encoded to make it URL-safe. We store both token (encrypted) and raw_token (plaintext for one-time validation).
Step 2: Store in Database
token, raw_token = generate_token()
request = DatasetAccessRequest(
user_id=user_id,
dataset_id=dataset_id,
token=token,
raw_token=raw_token, # used only once for validation
expires_at=datetime.utcnow() + timedelta(hours=24),
status='pending'
)
model.Session.add(request)
model.Session.commit()
We save the encrypted token, raw token, expiry, and status in the DB. The raw token will only be used once when the user clicks the email link.
Step 3: Email the Token
link = f"{h.url_for(controller='access', action='validate', qualified=True)}?token={raw_token}&dataset_id={dataset_id}"
email_body = f"""
Hi {admin['name']},
Click below to approve {new_user}'s request:
{link}
or reject the request:
{link}
The link expires in 24 hours.
"""
The email includes only the raw_token. We never expose or share the encrypted hash. This keeps the token lightweight and secure.
Step 4: Validate the Token
def validate_token(raw_token, dataset_id):
expected_token = base64.urlsafe_b64encode(
hashlib.sha256((raw_token + SECRET_KEY).encode()).digest()
).decode()
req = model.Session.query(DatasetAccessRequest).filter_by(
dataset_id=dataset_id,
raw_token=raw_token,
token=expected_token,
status='pending'
).first()
if req and req.expires_at > datetime.utcnow():
req.token_validated = True
model.Session.commit()
return True
return False
When the user clicks the link, we recompute the encrypted hash and match it against the stored one. If the record exists and hasn’t expired, the request is marked as validated.
Benefits of This Approach
- Tokens are tamper-proof and can’t be reverse-engineered
- Supports expiry (via TTL or timestamp)
- Token can be shared securely via email links
- Works seamlessly with CKAN’s existing plugin system
- Lightweight (no dependency on external encryption libs)
Stack Recap
PythonCKAN(plugin controller + models)hashlib,base64,uuidPostgreSQL(CKAN ORM)Email-based access flow
This was part of a larger workflow that eventually adds users to datasets after admin approval. Next up: handling admin-side review + role assignment.
If you’ve implemented token-based systems without JWT or OAuth, I’d love to hear how you approached validation. Drop a comment or share your experience!!
메타데이터
- post_id
- bbc96a39c3d3
- slug
- secure-encrypted-token-workflow-in-ckan-2-10-4-email-and-admin-level-validation-bbc96a39c3d3
- url
- https://medium.com/@paulshanit/secure-encrypted-token-workflow-in-ckan-2-10-4-email-and-admin-level-validation-bbc96a39c3d3
- canonical_url
- https://medium.com/@paulshanit/secure-encrypted-token-workflow-in-ckan-2-10-4-email-and-admin-level-validation-bbc96a39c3d3
- author_url
- https://medium.com/@paulshanit
- status
- ok
- fetched_at
- 2026-06-15 20:49:13