25. Tutorials
Step-by-step guides for implementing wFabricSecurity in your projects.
26. Prerequisites
Before starting these tutorials, ensure you have:
Requirement |
Description |
|---|---|
Python |
Version 3.10 or higher |
pip |
Latest version recommended |
Hyperledger Fabric |
Version 2.x or 3.x (for Fabric integration tutorials) |
MSP Directory |
Path to your organization’s MSP credentials |
Gateway Profile |
Path to your Fabric gateway connection profile |
# Check Python version
python --version
# Check pip version
pip --version
# Install wFabricSecurity
pip install wFabricSecurity
27. Tutorial 1: Basic Setup
Learn how to set up wFabricSecurity for simple security operations.
📚 Objectives
Install wFabricSecurity
Initialize the security system
Register identities
Create and verify messages
Step 1: Installation
pip install wFabricSecurity
Step 2: Basic Initialization
Create a new file basic_security.py:
from wFabricSecurity import FabricSecuritySimple
# Initialize with MSP path
security = FabricSecuritySimple(
msp_path="/path/to/your/msp"
)
print("Security system initialized!")
Step 3: Verify a Message
from wFabricSecurity import FabricSecuritySimple
security = FabricSecuritySimple(msp_path="/path/to/msp")
# Incoming message
incoming_message = {
"payload": '{"action": "process"}',
"sender": "CN=Master",
"signature": b"..." # Actual signature bytes
}
# Verify the message
result = security.verify_and_process(
payload=incoming_message["payload"],
sender=incoming_message["sender"]
)
if result:
print("✓ Message verified successfully!")
else:
print("✗ Verification failed!")
📊 Expected Output
Security system initialized!
✓ Message verified successfully!
✅ Complete Code
from wFabricSecurity import FabricSecuritySimple
def main():
# Initialize
security = FabricSecuritySimple(msp_path="/path/to/msp")
# Verify message
result = security.verify_and_process(
payload='{"action": "process"}',
sender="CN=Master"
)
print(f"Verification: {'✓ Success' if result else '✗ Failed'}")
if __name__ == "__main__":
main()
28. Tutorial 2: Identity Management
Managing identities and certificates in wFabricSecurity.
📚 Objectives
Understand X.509 certificates
Register participant identities
Manage certificate caching
Verify identity credentials
Step 1: Understanding MSP Configuration
The MSP (Membership Service Provider) contains:
msp/
├── cacerts/ # CA certificates
├── signcerts/ # Signing certificates
├── keystore/ # Private keys
└── tlscacerts/ # TLS CA certificates
Step 2: Register Participant Identity
from wFabricSecurity import FabricSecurity
# Full initialization
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
gateway_path="/path/to/gateway"
)
# Register your identity
security.register_identity()
print(f"Identity registered: {security.me}")
Step 3: Manage Multiple Participants
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.models import Participant
from wFabricSecurity.fabric_security.core.enums import ParticipantStatus
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
# Register participants
participants = [
Participant(
id="slave-1",
common_name="CN=Slave1",
msp_id="Org1MSP",
status=ParticipantStatus.ACTIVE
),
Participant(
id="slave-2",
common_name="CN=Slave2",
msp_id="Org1MSP",
status=ParticipantStatus.ACTIVE
)
]
# Register in system
for participant in participants:
security.register_participant(participant)
print(f"Registered {len(participants)} participants")
Step 4: Certificate Caching
from wFabricSecurity.fabric_security.crypto.identity import IdentityManager
# Initialize with caching
identity = IdentityManager(
cache_size=1024, # Max cached certificates
ttl=3600 # 1 hour TTL
)
# First call - fetches from disk
cert1 = identity.get_certificate("CN=Master")
print("Certificate loaded from disk")
# Second call - from cache
cert2 = identity.get_certificate("CN=Master")
print("Certificate served from cache")
# Check cache stats
stats = identity.get_cache_stats()
print(f"Cache hits: {stats['hits']}")
print(f"Cache misses: {stats['misses']}")
✅ Complete Code
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.models import Participant
from wFabricSecurity.fabric_security.core.enums import ParticipantStatus
def setup_identity_system():
# Initialize
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
# Register master identity
security.register_identity()
# Register other participants
participants = [
Participant(
id="slave-1",
common_name="CN=Slave1",
msp_id="Org1MSP",
status=ParticipantStatus.ACTIVE
)
]
for participant in participants:
security.register_participant(participant)
return security
if __name__ == "__main__":
security = setup_identity_system()
print("Identity system configured!")
29. Tutorial 3: Code Integrity
Implementing SHA-256 code integrity verification.
📚 Objectives
Compute file hashes
Register code integrity
Verify code integrity at runtime
Handle tampering detection
Step 1: Compute Code Hash
from wFabricSecurity.fabric_security.crypto.hashing import HashingService
hasher = HashingService()
# Hash a single file
file_hash = hasher.hash_file("path/to/your/code.py")
print(f"File hash: {file_hash}")
# Hash multiple files
files = ["main.py", "utils.py", "models.py"]
combined_hash = hasher.hash_files(files)
print(f"Combined hash: {combined_hash}")
Step 2: Register Code Integrity
from wFabricSecurity import FabricSecurity
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
# Register source code files
security.register_code(
files=["master.py", "utils.py"],
version="1.0.0"
)
print("Code integrity registered!")
Step 3: Verify Code Integrity
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.exceptions import CodeIntegrityError
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
try:
# Verify current code
security.verify_code_integrity()
print("✓ Code integrity verified!")
except CodeIntegrityError as e:
print(f"✗ Code tampering detected: {e}")
Step 4: Store Hash on Fabric Ledger
from wFabricSecurity import FabricSecurity
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
gateway_path="/path/to/gateway"
)
# Register and store on ledger
security.register_code(
files=["secure_module.py"],
version="1.0.0",
store_on_ledger=True # Store hash on Fabric
)
print("Code hash stored on Fabric ledger!")
📊 Expected Output
File hash: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
Combined hash: 7f83b1657ff1fc53b92dc18148a1d65d
✓ Code integrity verified!
✅ Complete Code
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.exceptions import CodeIntegrityError
def verify_application_integrity():
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
# Register code
security.register_code(
files=["main.py", "utils.py"],
version="1.0.0"
)
# Verify
try:
security.verify_code_integrity()
return True, "Code integrity verified"
except CodeIntegrityError as e:
return False, f"Tampering detected: {e}"
if __name__ == "__main__":
success, message = verify_application_integrity()
print(f"{'✓' if success else '✗'} {message}")
30. Tutorial 4: Communication Permissions
Setting up fine-grained communication permissions between participants.
📚 Objectives
Define permission types
Register communication rules
Check permission status
Handle permission denied scenarios
Step 1: Understanding Permission Types
from wFabricSecurity.fabric_security.core.enums import CommunicationDirection
# Available permission types
print(f"BIDIRECTIONAL: {CommunicationDirection.BIDIRECTIONAL}")
print(f"OUTBOUND: {CommunicationDirection.OUTBOUND}")
print(f"INBOUND: {CommunicationDirection.INBOUND}")
print(f"NONE: {CommunicationDirection.NONE}")
Step 2: Register Communication Permissions
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.enums import CommunicationDirection
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
# Register bidirectional communication (full peer-to-peer)
security.register_communication(
from_participant="CN=Master",
to_participant="CN=Slave",
direction=CommunicationDirection.BIDIRECTIONAL
)
# Register outbound-only (Master can send to Analytics)
security.register_communication(
from_participant="CN=Master",
to_participant="CN=Analytics",
direction=CommunicationDirection.OUTBOUND
)
# Register inbound-only (Analytics receives from others)
security.register_communication(
from_participant="CN=Sensor",
to_participant="CN=Analytics",
direction=CommunicationDirection.INBOUND
)
print("Communication permissions configured!")
Step 3: Check and Enforce Permissions
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.exceptions import PermissionDeniedError
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp"
)
# Register permissions
security.register_communication("CN=Master", "CN=Slave")
# Check if communication is allowed
if security.check_permission("CN=Master", "CN=Slave"):
print("✓ Communication allowed")
else:
print("✗ Communication denied")
# Try to send message (will raise if denied)
try:
security.send_message(
to="CN=Slave",
content="Hello, Slave!"
)
print("✓ Message sent successfully")
except PermissionDeniedError:
print("✗ Permission denied - cannot send to this recipient")
Step 4: Permission Matrix
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.enums import CommunicationDirection
security = FabricSecurity(me="Master", msp_path="/path/to/msp")
# Define organization permissions
permissions = [
("CN=Master", "CN=Slave1", CommunicationDirection.BIDIRECTIONAL),
("CN=Master", "CN=Slave2", CommunicationDirection.BIDIRECTIONAL),
("CN=Master", "CN=Analytics", CommunicationDirection.OUTBOUND),
("CN=Sensor1", "CN=Master", CommunicationDirection.INBOUND),
]
# Register all permissions
for from_cn, to_cn, direction in permissions:
security.register_communication(from_cn, to_cn, direction)
# Get permission matrix
matrix = security.get_permission_matrix()
print("Permission Matrix:")
for row in matrix:
print(f" {row['from']} -> {row['to']}: {row['direction']}")
✅ Complete Code
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.enums import CommunicationDirection
from wFabricSecurity.fabric_security.core.exceptions import PermissionDeniedError
def setup_permissions():
security = FabricSecurity(me="Master", msp_path="/path/to/msp")
# Configure permissions
security.register_communication(
"CN=Master", "CN=Slave",
CommunicationDirection.BIDIRECTIONAL
)
# Test permission
allowed = security.check_permission("CN=Master", "CN=Slave")
return allowed
if __name__ == "__main__":
result = setup_permissions()
print(f"Permission check: {'✓ Allowed' if result else '✗ Denied'}")
31. Tutorial 5: Rate Limiting
Implementing rate limiting to protect against DoS attacks.
📚 Objectives
Configure rate limiter
Implement token bucket algorithm
Handle rate limit exceeded
Configure per-participant limits
Step 1: Basic Rate Limiting
from wFabricSecurity.fabric_security.security.rate_limiter import RateLimiter
# Initialize rate limiter
limiter = RateLimiter(
rate=10, # 10 tokens per second
capacity=50, # Max 50 tokens (burst capacity)
participant="CN=Master"
)
# Check if request is allowed
for i in range(55):
if limiter.should_allow():
print(f"Request {i+1}: ✓ Allowed")
else:
print(f"Request {i+1}: ✗ Rate limited")
Step 2: Integration with Security System
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.exceptions import RateLimitExceededError
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
rate_limit=10, # 10 requests/second
rate_capacity=50 # Burst capacity
)
# Process request with rate limiting
def process_request(request_data: dict, sender: str):
# Check rate limit
if not security.check_rate_limit(sender):
raise RateLimitExceededError(f"Rate limit exceeded for {sender}")
# Process the request
return {"status": "success", "data": request_data}
# Test with multiple requests
for i in range(5):
try:
result = process_request(
{"id": i, "action": "process"},
sender="CN=Slave"
)
print(f"✓ Request {i+1}: {result['status']}")
except RateLimitExceededError as e:
print(f"✗ Request {i+1}: {e}")
Step 3: Per-Participant Rate Limits
from wFabricSecurity import FabricSecurity
security = FabricSecurity(me="Master", msp_path="/path/to/msp")
# Configure different limits per participant type
rate_configs = {
"CN=Master": {"rate": 100, "capacity": 500}, # High priority
"CN=Slave": {"rate": 50, "capacity": 200}, # Normal priority
"CN=Sensor": {"rate": 10, "capacity": 50}, # IoT devices
}
for participant, config in rate_configs.items():
security.configure_rate_limit(
participant=participant,
rate=config["rate"],
capacity=config["capacity"]
)
print("Rate limits configured per participant!")
📊 Token Bucket Visualization
Time ->
Token Bucket State:
t=0s: [●●●●●] 5/50 tokens
t=1s: [●●●●●●●] 7/50 tokens (added 2)
t=2s: [●●●●●●●●●] 9/50 tokens
...
t=25s: [●●●●●●●●●●●●●●●] 50/50 tokens (full)
Burst: Up to 50 requests can be made at once
✅ Complete Code
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.exceptions import RateLimitExceededError
def secure_request_handler(request_data: dict, sender: str):
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
rate_limit=10,
rate_capacity=50
)
if not security.check_rate_limit(sender):
raise RateLimitExceededError(f"Rate limit exceeded: {sender}")
return {"status": "processed", "sender": sender}
if __name__ == "__main__":
for i in range(3):
try:
result = secure_request_handler(
{"id": i},
sender="CN=Master"
)
print(f"✓ Request {i+1}: {result['status']}")
except RateLimitExceededError as e:
print(f"✗ Rate limited: {e}")
32. Tutorial 6: Fabric Integration
Connecting wFabricSecurity to a Hyperledger Fabric network.
📚 Objectives
Connect to Fabric gateway
Interact with chaincode
Store data on Fabric ledger
Query ledger data
Step 1: Gateway Connection Setup
from wFabricSecurity.fabric_security.fabric.gateway import FabricGateway
# Initialize gateway
gateway = FabricGateway(
gateway_path="/path/to/connection-profile.yaml",
identity="Admin@org1.example.com",
msp_path="/path/to/msp"
)
# Connect
gateway.connect()
print("Connected to Fabric network!")
# Don't forget to disconnect when done
# gateway.disconnect()
Step 2: Access Network and Contract
from wFabricSecurity import FabricSecurity
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
gateway_path="/path/to/gateway"
)
# Access network
network = security.get_network("mychannel")
# Access chaincode
contract = security.get_contract("my_chaincode")
print(f"Network: {network.channel_name}")
print(f"Contract: {contract.name}")
Step 3: Submit Transactions
from wFabricSecurity import FabricSecurity
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
gateway_path="/path/to/gateway"
)
# Get contract
contract = security.get_contract("secure_chaincode")
# Submit transaction (writes to ledger)
result = contract.submit_transaction(
"CreateAsset",
"asset123",
"data_payload",
"Master"
)
print(f"Transaction submitted: {result}")
Step 4: Query Ledger
from wFabricSecurity import FabricSecurity
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
gateway_path="/path/to/gateway"
)
contract = security.get_contract("secure_chaincode")
# Query (read-only, no transaction fees)
result = contract.evaluate_transaction(
"ReadAsset",
"asset123"
)
print(f"Asset data: {result}")
Step 5: Complete Fabric Workflow
from wFabricSecurity import FabricSecurity
from wFabricSecurity.fabric_security.core.exceptions import (
CodeIntegrityError,
PermissionDeniedError
)
def secure_fabric_operation():
# Initialize with full configuration
security = FabricSecurity(
me="Master",
msp_path="/path/to/msp",
gateway_path="/path/to/gateway"
)
# Register identity
security.register_identity()
# Register code integrity
security.register_code(["master.py"], "1.0.0", store_on_ledger=True)
# Register permissions
security.register_communication("CN=Master", "CN=Slave")
# Get contract
contract = security.get_contract("secure_chaincode")
# Create and verify message
message = security.create_message(
recipient="CN=Slave",
content='{"action": "process_asset", "asset_id": "123"}'
)
if security.verify_message(message):
# Submit to Fabric
result = contract.submit_transaction(
"ProcessAsset",
message.payload
)
return True, result
else:
return False, "Verification failed"
if __name__ == "__main__":
success, result = secure_fabric_operation()
print(f"{'✓' if success else '✗'} {result}")
📊 Architecture Diagram
33. Best Practices
🎯 Security Best Practices
Always verify signatures before processing messages
Check code integrity at application startup
Use TLS for all network communications
Implement rate limiting to prevent DoS attacks
Store sensitive data (keys, certs) securely
Rotate credentials regularly
🚀 Performance Best Practices
Enable certificate caching with appropriate TTL
Use connection pooling for Fabric gateways
Batch operations when possible
Monitor rate limits per participant
Use local storage for development/testing
📝 Logging Best Practices
Log all security events (verifications, failures)
Include participant IDs in logs
Use structured logging format
Set appropriate log levels (DEBUG, INFO, WARNING, ERROR)
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Use in your code
logger.info("Security verification successful")
logger.warning("Rate limit approaching for participant CN=Master")
logger.error("Code integrity check failed")
See also
API Reference - Complete API documentation
Getting Started - Quick start guide
Architecture - System architecture details
FAQ - Frequently asked questions