src/platform_network/security/miner_auth.py:150-198). This page shows exactly what to
sign.
Required headers
You send four headers on every signed upload (src/platform_network/security/miner_auth.py:159-162, docs/miner/README.md:90-95):
| Header | Meaning | Source |
|---|---|---|
X-Hotkey | Your ss58 hotkey address | src/platform_network/security/miner_auth.py:159 |
X-Signature | Signature over the canonical message | src/platform_network/security/miner_auth.py:160 |
X-Nonce | Unique per-request value (replay protection) | src/platform_network/security/miner_auth.py:161 |
X-Timestamp | Unix seconds, checked for freshness | src/platform_network/security/miner_auth.py:162-169 |
missing <header>
(src/platform_network/security/miner_auth.py:230-234).
The canonical message
The signed message is built exactly as (src/platform_network/security/miner_auth.py:96-111):
netuidis100(src/platform_network/config/settings.py:12).challenge_slugis the resolved challenge slug, for exampleagent-challengeorprism(src/platform_network/master/app_proxy.py:438).METHODis the uppercased HTTP method (src/platform_network/security/miner_auth.py:109).pathis the request path (src/platform_network/master/app_proxy.py:435).hotkey,nonce, andtimestampare the same values as your headers (src/platform_network/security/miner_auth.py:171-179).body_hashis the SHA-256 hex digest of the raw request body (src/platform_network/security/miner_auth.py:170).
How to sign
Compute the body hash
Take the SHA-256 of the exact bytes you will upload and hex-encode it
(
src/platform_network/security/miner_auth.py:170).Assemble the canonical message
Concatenate the fields with the
platform-upload-v1: prefix and colon separators,
using netuid 100, the challenge slug, the uppercased method, the path, your hotkey,
your nonce, your timestamp, and the body hash
(src/platform_network/security/miner_auth.py:96-111).Sign with your hotkey
Sign the message bytes with your hotkey keypair. Verification uses the substrate ss58
keypair
verify (src/platform_network/security/miner_auth.py:114-121).Encode the signature
Provide the signature as a hex string, with or without a
0x prefix
(src/platform_network/security/miner_auth.py:222-227).Freshness and replay
- Freshness: a timestamp more than
300seconds from server time fails withstale signature(src/platform_network/security/miner_auth.py:168-169,src/platform_network/config/settings.py:33). - Replay: each nonce is reserved per netuid, challenge, and hotkey; a reused nonce fails
with
nonce already used(src/platform_network/security/miner_auth.py:60-90). Nonces are retained for86,400seconds (src/platform_network/config/settings.py:34). - Timestamp format: a non-integer timestamp fails with
invalid timestamp(src/platform_network/security/miner_auth.py:163-166).
Identity resolution
After the signature verifies, your hotkey is resolved to a UID from the metagraph (src/platform_network/security/miner_auth.py:183,200-219):
- An unregistered hotkey fails with
unknown hotkey(src/platform_network/security/miner_auth.py:213-215). - UID
0is blocked and fails withblocked uid(src/platform_network/security/miner_auth.py:143,217-218).
Next steps
Submitting your work
Apply this signature to the upload endpoints.
Troubleshooting
Resolve signature and replay errors.