Client Certificate Authentication¶
This guide shows you how to use client certificates for authentication in Gemini, both as a server administrator requiring certificates and as a client using certificates to authenticate.
Overview¶
Client certificates in Gemini provide a lightweight authentication mechanism without passwords. Servers can require certificates for specific paths (like /admin/ or /app/), and clients present certificates to prove their identity.
Generate a Client Certificate¶
Use the nauyaca cert generate command to create a self-signed certificate for client authentication:
# Generate a certificate named 'myidentity'
nauyaca cert generate myidentity
# Generate with custom validity period
nauyaca cert generate myidentity --valid-days 730
# Generate in a specific directory
nauyaca cert generate myidentity --output-dir ./certs/
# Overwrite existing certificate
nauyaca cert generate myidentity --force
By default, certificates are created in ~/.nauyaca/certs/ with:
- Certificate file:
~/.nauyaca/certs/myidentity.pem - Private key:
~/.nauyaca/certs/myidentity.key(with restrictive permissions)
The certificate name you provide becomes the Common Name (CN) in the certificate, which some Gemini servers may display as your identity.
View Certificate Information¶
To view details about a certificate, including its fingerprint:
This displays:
- Subject and issuer
- Serial number
- Validity period (not before/not after dates)
- SHA-256 fingerprint (used for authorization)
Require Client Certificates (Server)¶
As a server administrator, you can require client certificates for specific paths using the [[certificate_auth.paths]] section in your configuration file.
Require Any Certificate for a Path¶
To require that clients present any valid certificate for a specific path:
This configuration:
- Applies to all URLs starting with
/app/ - Returns status 60 (CLIENT CERTIFICATE REQUIRED) if no certificate is presented
- Accepts any valid client certificate
Create Public Areas Within Authenticated Paths¶
Rules are checked in order, so you can create public areas within authenticated paths:
# Public area - no certificate needed
[[certificate_auth.paths]]
prefix = "/app/public/"
require_cert = false
# Rest of /app/ requires certificate
[[certificate_auth.paths]]
prefix = "/app/"
require_cert = true
With this configuration:
/app/public/and its subdirectories are accessible to everyone- All other
/app/paths require a client certificate - Order matters: the more specific rule must come first
Restrict to Specific Certificates¶
For administrative areas or user-specific content, you can restrict access to specific certificates by their fingerprint.
Extract Certificate Fingerprint¶
First, get the fingerprint of the client certificate you want to authorize:
Look for the line starting with Fingerprint (SHA-256):. It will look like:
Configure Allowed Fingerprints¶
Add the fingerprint to your server configuration:
[[certificate_auth.paths]]
prefix = "/admin/"
require_cert = true
allowed_fingerprints = [
"sha256:a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456",
]
This configuration:
- Requires a client certificate for
/admin/ - Only accepts the specific certificate(s) listed
- Returns status 61 (CERTIFICATE NOT AUTHORISED) if a different certificate is presented
- Returns status 60 (CLIENT CERTIFICATE REQUIRED) if no certificate is presented
Multiple Users¶
To allow multiple users with different certificates:
[[certificate_auth.paths]]
prefix = "/admin/"
require_cert = true
allowed_fingerprints = [
"sha256:admin1-fingerprint-here...",
"sha256:admin2-fingerprint-here...",
"sha256:admin3-fingerprint-here...",
]
Send Client Certificate (Client)¶
As a client, use the --client-cert and --client-key options to authenticate:
nauyaca get gemini://secure.example.com/app/ \
--client-cert ~/.nauyaca/certs/myidentity.pem \
--client-key ~/.nauyaca/certs/myidentity.key
Both options must be provided together:
--client-cert: Path to your certificate file (PEM format)--client-key: Path to your private key file (PEM format)
Using the Library API¶
When using Nauyaca as a library in Python:
import asyncio
from pathlib import Path
from nauyaca.client.session import GeminiClient
async def fetch_with_cert():
cert_path = Path.home() / ".nauyaca" / "certs" / "myidentity.pem"
key_path = Path.home() / ".nauyaca" / "certs" / "myidentity.key"
async with GeminiClient(
client_cert=cert_path,
client_key=key_path,
) as client:
response = await client.get("gemini://secure.example.com/app/")
print(response.body)
asyncio.run(fetch_with_cert())
Handle Certificate Errors¶
When accessing certificate-protected resources, you may encounter these status codes:
Status 60: CLIENT CERTIFICATE REQUIRED¶
The server requires a client certificate, but you didn't provide one.
Solution: Provide a client certificate:
nauyaca get gemini://example.com/app/ \
--client-cert ~/.nauyaca/certs/myidentity.pem \
--client-key ~/.nauyaca/certs/myidentity.key
Status 61: CERTIFICATE NOT AUTHORISED¶
You provided a client certificate, but it's not authorized for this resource.
Possible causes:
- The server requires a specific certificate, and yours isn't on the list
- Your certificate has expired
- You're using the wrong certificate for this resource
Solution: Verify you're using the correct certificate, or contact the server administrator to have your certificate authorized.
Status 62: CERTIFICATE NOT VALID¶
Your client certificate is invalid or malformed.
Possible causes:
- Certificate file is corrupted
- Certificate has expired
- Certificate format is incorrect
Solution: Generate a new certificate or verify the certificate file is valid:
Common Patterns¶
Admin Area with Specific Certificate¶
Require a specific administrator certificate for the admin area:
[[certificate_auth.paths]]
prefix = "/admin/"
require_cert = true
allowed_fingerprints = [
"sha256:admin-cert-fingerprint...",
]
Multi-User Application with Tiered Access¶
Create different access levels with different certificate requirements:
# Public area - no auth
[[certificate_auth.paths]]
prefix = "/app/public/"
require_cert = false
# User area - any certificate
[[certificate_auth.paths]]
prefix = "/app/users/"
require_cert = true
# Admin area - specific certificates only
[[certificate_auth.paths]]
prefix = "/app/admin/"
require_cert = true
allowed_fingerprints = [
"sha256:admin1-fingerprint...",
"sha256:admin2-fingerprint...",
]
# Default for /app/ - require any certificate
[[certificate_auth.paths]]
prefix = "/app/"
require_cert = true
Personal Capsule with Private Section¶
Serve public content by default, but require your personal certificate for private content:
[[certificate_auth.paths]]
prefix = "/private/"
require_cert = true
allowed_fingerprints = [
"sha256:my-personal-cert-fingerprint...",
]
Testing with Self-Signed Certificates¶
During development, require any certificate for testing authentication flows:
[[certificate_auth.paths]]
prefix = "/test-auth/"
require_cert = true
# No allowed_fingerprints = accept any valid certificate
Security Considerations¶
Certificate Storage¶
- Store private keys securely with restrictive permissions (0600)
- Nauyaca automatically sets correct permissions when generating certificates
- Never share your private key files
- Back up your certificates if they represent persistent identities
Certificate Rotation¶
Certificates have expiration dates. Plan for certificate rotation:
- Generate a new certificate before the old one expires
- Add both fingerprints to the server configuration temporarily
- Switch to using the new certificate on the client
- Remove the old fingerprint from the server after transition
Example transition configuration:
[[certificate_auth.paths]]
prefix = "/admin/"
require_cert = true
allowed_fingerprints = [
"sha256:old-cert-fingerprint...", # Remove after transition
"sha256:new-cert-fingerprint...", # Keep this one
]
Fingerprint Verification¶
Always verify fingerprints through a secure out-of-band channel:
- Don't accept fingerprints sent over email or instant messaging
- Use HTTPS, SSH, or in-person verification to exchange fingerprints
- Document which certificate fingerprints belong to which users
See Also¶
- Server Configuration - Full server configuration options
- Security Best Practices - Security considerations
- API Reference: Certificates - Certificate management API