A secure, privacy-focused push notification server for Tailchat.
The Push Notification Server (PNServer) is responsible for delivering push notifications to iOS and Android devices while maintaining user privacy and security.
- End-to-end message privacy
- No message content storage
- Minimal data collection
- Token-based authentication
- Rate limiting protection
- Messages are never stored on the server
- Only device tokens and minimal metadata are kept
- No access to message content
- No logging of message contents
- Uses token-based authentication
- Tokens are stored securely
- Old tokens are automatically invalidated
- Prevents abuse through rate limiting
- 30-second delay between pushes for unverified senders
- Shorter delays for verified senders
Plan to be done when there is indeed a good demand for it.
We are currently waiting for upstream fixes in the APNs client package to resolve security vulnerabilities. The issues are:
- Dependency chain security updates needed
- Certificate validation improvements pending
- HTTP/2 connection handling fixes
Once these issues are resolved upstream, we will update our implementation accordingly.
- Client sends push request
- Server validates tokens
- Rate limiting check
- Push notification sent to Apple/Google services
- No message content retained
- Environment-based settings
- Configurable rate limits
- Token validation rules
- Logging levels
| Variable | Description | Default |
|---|---|---|
| APN_AUTH_TYPE | Authentication type for APNs | token |
| APN_KEY_PATH | Path to .p8 key file | ./aps.p8 |
| APN_KEY_ID | Key ID from Apple Developer portal | required |
| APN_TEAM_ID | Apple Developer Team ID | required |
| APN_BUNDLE_ID | App Bundle ID | required |
| APN_DEVELOPMENT | Use sandbox environment | true |
| REDIS_PASSWORD | Redis password | required |
| PORT | Server port | 9000 |
- Docker and Docker Compose
- Apple Developer Account (for iOS notifications)
- Firebase project (for Android notifications)
- Copy the example environment file:
cp .env.example .env- Edit
.envwith your configuration:
# Apple Push Notification Settings
export APN_AUTH_TYPE=token # Use 'token' for JWT-based auth
export APN_KEY_PATH=./aps.p8 # Path to your .p8 key file
export APN_KEY_ID=your_key_id # Key ID from Apple Developer portal
export APN_TEAM_ID=your_team_id # Your Apple Developer Team ID
export APN_BUNDLE_ID=your.app.bundle.id # Your app's bundle ID
export APN_DEVELOPMENT=true # Use sandbox environment
# Redis Settings
export REDIS_PASSWORD=your_secure_password
# Server Settings
export PORT=9000- Create or modify your
docker-compose.yml:
services:
pnserver:
build:
context: .
dockerfile: Dockerfile
ports:
- "9000:9000"
environment:
- APN_AUTH_TYPE=${APN_AUTH_TYPE}
- APN_KEY_PATH=${APN_KEY_PATH}
- APN_KEY_ID=${APN_KEY_ID}
- APN_TEAM_ID=${APN_TEAM_ID}
- APN_BUNDLE_ID=${APN_BUNDLE_ID}
- APN_DEVELOPMENT=${APN_DEVELOPMENT}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- PORT=${PORT}
volumes:
- ./aps.p8:/app/aps.p8:ro
depends_on:
- redis
redis:
image: redis:alpine
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
redis_data:- Start the services:
docker compose up -d- Check logs:
docker compose logs -f pnserverFor local development without Docker:
- Source the environment variables:
source .env- Run Redis (if not already running):
docker run -d \
-p 6379:6379 \
--name redis \
redis:alpine \
redis-server --requirepass "${REDIS_PASSWORD}"- Run the server:
go run main.go- Enhanced token rotation
- Additional rate limiting strategies
- Improved error handling
- Better metrics and monitoring
Please read our Contributing Guidelines before submitting changes.
BSD 3-Clause License. See LICENSE for details.