Dynamic Client Registration is the Missing Piece for Mobile and CLI Applications
Published by @smokesignal.events on 2025-08-07 19:45 UTC.
ATProtocol takes an interesting approach to OAuth by requiring client_ids to be fully-qualified HTTPS URLs pointing to publicly-accessible JSON metadata documents. This design enables global client identification across all PDS instances without any prior coordination. Developers can build once and authenticate everywhere across the decentralized network.
The system works well for web applications. A developer creates a client metadata document, hosts it at a stable URL, and can immediately start authenticating users across the entire network. No manual registration with each PDS, no waiting for approval processes, no managing different client credentials for different servers. The authorization server fetches and validates the metadata on-demand during the initial flow, automatically registering the client without any prior setup.
The security model incorporates modern standards by mandating DPoP (Demonstrating Proof of Possession) for all clients, which prevents token replay attacks even if tokens are intercepted. The requirement for HTTPS-hosted metadata documents provides cryptographic verification of client identity through existing web PKI infrastructure. This addresses the trust problem in a decentralized network where no central authority exists to validate client registrations.
For web applications, this approach works quite well. The infrastructure requirements align with typical web deployment patterns—if you're hosting a web app, you're already set up to host a metadata document. The browser-based OAuth flows integrate smoothly, and the security model provides good protection against common attack vectors. This foundation works effectively for its intended use case.
Why Mobile and CLI Applications Need More
However, the current implementation creates significant barriers for two critical categories of applications: mobile apps and command-line tools. These applications have fundamentally different operational characteristics and security models that don't align well with the requirement to host public metadata documents.
The Mobile App Dilemma
Mobile applications face a unique challenge: they're distributed through app stores as compiled binaries that users install on their devices, but ATProtocol OAuth requires them to maintain web infrastructure. Consider a simple mobile app for posting to Bluesky—perhaps a specialized photography app or a streamlined reader. Under the current model, this app must:
- Maintain a web server solely to host a client metadata document
- Ensure 24/7 availability of this infrastructure (if the metadata URL goes down, no users can authenticate)
- Handle operational complexity that has nothing to do with the app's core functionality
- Absorb hosting costs even for free or open-source applications
This creates a substantial barrier to entry. A talented mobile developer who wants to build a great ATProtocol experience shouldn't need to become a web infrastructure operator. The requirement fundamentally changes the economics of mobile app development—what could be a one-time development effort becomes an ongoing operational commitment.
More critically, the current model doesn't support per-installation credentials, a security best practice for mobile applications. When every installation of an app uses the same client_id (the metadata URL), you lose the ability to:
- Revoke access for specific compromised devices
- Track usage patterns per installation for security monitoring
- Implement device-specific rate limiting
- Provide users with granular control over their authorized devices
The CLI Tool Challenge
Command-line tools face even steeper challenges. Developers routinely create CLI tools for automation, research, and system administration. These tools are often:
- Personal scripts that shouldn't require public infrastructure
- Internal enterprise tools that need to work behind firewalls
- Open-source utilities that users run on their own machines
- Development tools that need to work in varied network environments
Requiring each of these tools to host public metadata documents is simply impractical. The localhost exception (http://127.0.0.1/
) helps during development but doesn't address production use cases. A researcher wanting to analyze public ATProtocol data, a system administrator automating account management, or a developer building deployment scripts—all face the same barrier: they must operate web infrastructure just to authenticate.
The current 30-minute token lifetime for public clients compounds these issues. CLI tools that perform long-running operations must implement complex token refresh logic, and the 7-day maximum session lifetime means users must frequently re-authenticate through browser flows—a particularly poor experience in headless server environments.
How RFC 7591 Addresses Mobile Authentication Needs
RFC 7591's Dynamic Client Registration protocol, specifically Section A.4.1, provides a comprehensive solution for mobile authentication challenges. The specification explicitly acknowledges that "mobile applications are considered public clients" and provides mechanisms tailored to their unique requirements.
Per-Installation Registration
The RFC's mobile guidance centers on a critical security principle: each installation should obtain its own credentials. Section A.4.1 states:
"Mobile applications that are dynamically registered are able to generate a unique client identifier for each installation, providing device-specific identification."
This approach transforms the security model. Instead of every instance of "SuperPhoto for Bluesky" sharing the same client credentials embedded in the app binary, each installation registers itself with the PDS during initial setup. This provides:
- Granular revocation: Users can revoke access for a lost phone without affecting their tablet
- Compromise isolation: If one device is compromised, other installations remain secure
- Usage tracking: The PDS can implement per-device rate limiting and anomaly detection
- User control: Settings interfaces can show "SuperPhoto on iPhone 12" vs "SuperPhoto on iPad Pro"
Platform-Specific Redirect URIs
Mobile platforms use various mechanisms for OAuth redirect handling, from custom URL schemes to Universal Links (iOS) and App Links (Android). RFC 7591 accommodates this diversity by allowing clients to register platform-specific redirect URIs during the registration process:
{
"redirect_uris": [
"com.example.app://oauth/callback",
"https://app.example.com/oauth/ios",
"https://app.example.com/oauth/android"
]
}
The specification recognizes that mobile apps cannot use traditional web-based redirects and explicitly supports custom schemes, making it possible for apps to complete OAuth flows without requiring web infrastructure.
Secure Credential Storage
Section A.4.1 emphasizes that dynamically registered credentials should be stored using platform-specific secure storage mechanisms:
"Client credentials obtained via dynamic registration MUST be stored in secure storage appropriate to the platform, such as the iOS Keychain or Android Keystore."
This guidance ensures that even though mobile apps are public clients (cannot keep secrets in their distributed code), the per-installation credentials obtained through DCR can be properly secured using hardware-backed secure enclaves available on modern devices.
JWK-Based Authentication
The RFC supports registering public keys (JWKs) during client registration, enabling mobile apps to use asymmetric cryptography for authentication:
{
"token_endpoint_auth_method": "private_key_jwt",
"jwks": {
"keys": [{
"kty": "RSA",
"use": "sig",
"kid": "device-key-001",
"n": "...",
"e": "AQAB"
}]
}
}
This is particularly powerful on mobile platforms where modern devices provide hardware-backed key generation and storage. The private key never leaves the secure enclave, providing stronger security than any shared secret approach.
Implementing DCR for ATProtocol: Request and Response Examples
Here's how Dynamic Client Registration could work in practice for ATProtocol PDS implementations, following RFC 7591 while maintaining compatibility with ATProtocol's security model.
Mobile Application Registration Request
When a mobile app launches for the first time, it would generate a unique keypair and register itself with the user's PDS:
POST /oauth/register HTTP/1.1
Host: alice.pds.example.com
Content-Type: application/json
{
"client_name": "SuperPhoto for Bluesky",
"client_uri": "https://superphoto.app",
"logo_uri": "https://superphoto.app/icon.png",
"redirect_uris": [
"com.superphoto.app://oauth/callback",
"https://superphoto.app/oauth/mobile"
],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "private_key_jwt",
"application_type": "native",
"contacts": ["support@superphoto.app"],
"policy_uri": "https://superphoto.app/privacy",
"tos_uri": "https://superphoto.app/terms",
"jwks": {
"keys": [{
"kty": "EC",
"use": "sig",
"crv": "P-256",
"kid": "2024-device-key",
"x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
"y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"
}]
},
"dpop_bound_access_tokens": true,
"software_id": "com.superphoto.app",
"software_version": "2.3.1"
}
Successful Registration Response
The PDS would validate the request and return unique credentials for this specific installation:
HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-store
{
"client_id": "dcr_3h7kb2pd5t8w9r",
"client_id_issued_at": 1735689600,
"client_secret": "yk_2KsJ5P9rN3mXvQ7dLwR8T6",
"client_secret_expires_at": 0,
"registration_access_token": "reg_7Fjw9kLm3Nv8Qp2Sx5Ty",
"registration_client_uri": "https://alice.pds.example.com/oauth/clients/dcr_3h7kb2pd5t8w9r",
"client_name": "SuperPhoto for Bluesky",
"redirect_uris": [
"com.superphoto.app://oauth/callback",
"https://superphoto.app/oauth/mobile"
],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "private_key_jwt",
"application_type": "native",
"dpop_bound_access_tokens": true,
"software_id": "com.superphoto.app",
"software_version": "2.3.1",
"scope": "atproto",
"jwks": {
"keys": [{
"kty": "EC",
"use": "sig",
"crv": "P-256",
"kid": "2024-device-key",
"x": "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
"y": "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM"
}]
}
}
CLI Tool Registration
Command-line tools could use a simplified registration flow, appropriate for their operational context:
POST /oauth/register HTTP/1.1
Host: alice.pds.example.com
Content-Type: application/json
{
"client_name": "atproto-cli v1.2.0",
"grant_types": ["urn:ietf:params:oauth:grant-type:device_code"],
"response_types": ["device_code"],
"token_endpoint_auth_method": "none",
"application_type": "native",
"software_id": "com.example.atproto-cli",
"software_version": "1.2.0"
}
The response would include a client_id suitable for device flow authentication:
HTTP/1.1 201 Created
Content-Type: application/json
{
"client_id": "dcr_cli_8j3kd9sk2",
"client_id_issued_at": 1735689600,
"registration_access_token": "reg_Kj39Fk2Lm8Nv",
"registration_client_uri": "https://alice.pds.example.com/oauth/clients/dcr_cli_8j3kd9sk2",
"client_name": "atproto-cli v1.2.0",
"grant_types": ["urn:ietf:params:oauth:grant-type:device_code"],
"token_endpoint_auth_method": "none",
"application_type": "native"
}
Integration with Existing ATProtocol OAuth
The beauty of RFC 7591 is that it can coexist with ATProtocol's current URL-based client identification. The PDS could support both:
- URL-based clients: Continue to work exactly as they do today
- Dynamically registered clients: Use the DCR endpoint for registration
The authorization server would simply check if a client_id is a URL (existing behavior) or a DCR-issued identifier (new behavior). This allows for a smooth transition and backwards compatibility with existing clients while enabling the new functionality for mobile and CLI applications.
Mobile Development Becomes Accessible
With DCR support, mobile developers could focus on what they do best—creating great user experiences—without becoming web infrastructure operators. The registration happens automatically when users first launch the app:
- App launches → Checks for stored credentials
- No credentials found → Registers with user's PDS
- Credentials received → Stored in platform secure storage
- Future launches → Use stored credentials
No web servers. No hosting costs. No operational burden. Just a clean, secure authentication flow that works offline-first and provides better security through per-installation credentials.
The security benefits are substantial:
- Compromised devices can be revoked without affecting other installations
- Usage patterns can be tracked per-device for anomaly detection
- Rate limiting can be applied per-installation to prevent abuse
- User control improves with clear device management interfaces
CLI Tools Become Practical
For command-line tools, DCR would eliminate the current friction entirely. Developers could create tools that self-register on first use:
$ atproto-tool sync-posts
First time setup required. Authenticating with your PDS...
Enter your handle: alice.bsky.social
Authenticating... [opens browser for OAuth consent]
✓ Authentication successful! Credentials saved.
Syncing posts... Done!
The tool registers itself, completes the OAuth flow (using device flow for headless environments), and stores credentials locally. No metadata hosting, no public URLs, no infrastructure requirements.
This enables entire categories of tools that are currently impractical:
- Personal automation scripts for managing your ATProtocol presence
- Research tools for analyzing public data
- Backup utilities for exporting your content
- Development tools for testing and debugging
- Enterprise automation for managing organizational accounts
Maintaining Ecosystem Innovation
Crucially, adding DCR support wouldn't fragment the ecosystem or complicate the protocol. Web applications would continue using URL-based client identification—the current approach works perfectly for them. Mobile and CLI applications would use DCR where it makes sense. The authorization server handles both seamlessly.
This pragmatic approach acknowledges that different types of applications have different needs. Web apps need global portability across all PDS instances. Mobile apps need per-installation security without infrastructure overhead. CLI tools need simplicity and local operation. One size doesn't fit all, and that's okay.
The Path Forward
The ATProtocol community has already recognized these challenges. GitHub discussions (OAuth Roadmap #2656) show active engagement around OAuth limitations for mobile and CLI use cases. The Bluesky team has acknowledged the need for better solutions. Adding RFC 7591 support represents a natural evolution that:
- Preserves the innovation of URL-based client identification for web apps
- Adds flexibility for mobile and CLI applications with different needs
- Improves security through per-installation credentials
- Reduces barriers to ecosystem participation
- Maintains compatibility with existing OAuth infrastructure
The implementation work is straightforward—many OAuth libraries already support DCR, and the protocol is well-understood with years of production use across providers like Auth0, Okta, and Keycloak. The PDS reference implementation could add a /oauth/register
endpoint that follows RFC 7591, storing registered clients in the same database used for other OAuth state.
Conclusion: Completing the OAuth Story
ATProtocol's URL-based client identification works well for web applications and enables portability across the network. Adding more complete RFC 7591 Dynamic Client Registration support would extend this foundation to properly support mobile and CLI applications.
The benefits are clear: mobile developers could build applications without maintaining web infrastructure, security would improve through per-installation credentials, and CLI tools could operate without public hosting requirements. This isn't about replacing the current system, it's about expanding it to support different application types with different needs.
The technical specification exists, the implementation patterns are proven, and the community has identified the need. Adding Dynamic Client Registration to ATProtocol would be a welcome addition to the ATmosphere.