Add sentry, set csp reporting API
This commit is contained in:
4
Gemfile
4
Gemfile
@@ -37,6 +37,10 @@ gem "webauthn", "~> 3.0"
|
||||
# Public Suffix List for domain parsing
|
||||
gem "public_suffix", "~> 6.0"
|
||||
|
||||
# Error tracking and performance monitoring (optional, configured via SENTRY_DSN)
|
||||
gem "sentry-ruby", "~> 5.18"
|
||||
gem "sentry-rails", "~> 5.18"
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
gem "tzinfo-data", platforms: %i[ windows jruby ]
|
||||
|
||||
|
||||
@@ -100,7 +100,10 @@ module Admin
|
||||
params.require(:application).permit(
|
||||
:name, :slug, :app_type, :active, :redirect_uris, :description, :metadata,
|
||||
:domain_pattern, :landing_url, headers_config: {}
|
||||
)
|
||||
).tap do |whitelisted|
|
||||
# Remove client_secret from params if present (shouldn't be updated via form)
|
||||
whitelisted.delete(:client_secret)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ class Application < ApplicationRecord
|
||||
validates :app_type, presence: true,
|
||||
inclusion: { in: %w[oidc forward_auth] }
|
||||
validates :client_id, uniqueness: { allow_nil: true }
|
||||
validates :client_secret, presence: true, if: -> { oidc? && new_record? }
|
||||
validates :client_secret, presence: true, on: :create, if: -> { oidc? }
|
||||
validates :domain_pattern, presence: true, uniqueness: { case_sensitive: false }, if: :forward_auth?
|
||||
validates :landing_url, format: { with: URI::regexp(%w[http https]), allow_nil: true, message: "must be a valid URL" }
|
||||
|
||||
|
||||
@@ -83,4 +83,14 @@ Rails.application.configure do
|
||||
|
||||
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
|
||||
# config.generators.apply_rubocop_autocorrect_after_generate!
|
||||
|
||||
# Sentry configuration for development
|
||||
# Only enabled if SENTRY_DSN environment variable is set and explicitly enabled
|
||||
if ENV["SENTRY_DSN"].present? && ENV["SENTRY_ENABLED_IN_DEVELOPMENT"] == "true"
|
||||
config.sentry.enabled = true
|
||||
|
||||
# High sample rates for development debugging
|
||||
config.sentry.traces_sample_rate = ENV.fetch("SENTRY_TRACES_SAMPLE_RATE", 0.5).to_f
|
||||
config.sentry.profiles_sample_rate = ENV.fetch("SENTRY_PROFILES_SAMPLE_RATE", 0.2).to_f
|
||||
end
|
||||
end
|
||||
|
||||
@@ -133,4 +133,18 @@ Rails.application.configure do
|
||||
|
||||
# Skip DNS rebinding protection for the default health check endpoint.
|
||||
config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
|
||||
# Sentry configuration for production
|
||||
# Only enabled if SENTRY_DSN environment variable is set
|
||||
if ENV["SENTRY_DSN"].present?
|
||||
config.sentry.enabled = true
|
||||
|
||||
# Performance monitoring: sample 20% of transactions for traces
|
||||
# Adjust based on your traffic volume and Sentry plan limits
|
||||
config.sentry.traces_sample_rate = ENV.fetch("SENTRY_TRACES_SAMPLE_RATE", 0.2).to_f
|
||||
|
||||
# Continuous profiling: disabled by default in production due to cost
|
||||
# Enable temporarily for performance investigations if needed
|
||||
config.sentry.profiles_sample_rate = ENV.fetch("SENTRY_PROFILES_SAMPLE_RATE", 0.0).to_f
|
||||
end
|
||||
end
|
||||
|
||||
@@ -50,4 +50,8 @@ Rails.application.configure do
|
||||
|
||||
# Raise error when a before_action's only/except options reference missing actions.
|
||||
config.action_controller.raise_on_missing_callback_actions = true
|
||||
|
||||
# Disable Sentry in test environment to avoid interference with tests
|
||||
# Sentry can be explicitly enabled for integration testing if needed
|
||||
config.sentry.enabled = false
|
||||
end
|
||||
|
||||
@@ -53,6 +53,7 @@ Rails.application.configure do
|
||||
# Additional security headers for WebAuthn
|
||||
# Required for WebAuthn to work properly
|
||||
policy.require_trusted_types_for :none
|
||||
policy.report_uri = "/api/csp-violation-report"
|
||||
end
|
||||
|
||||
# Start with CSP in report-only mode for testing
|
||||
|
||||
@@ -44,10 +44,7 @@ Then set it securely:
|
||||
# Generate key
|
||||
bin/generate_oidc_key > oidc_private_key.pem
|
||||
|
||||
# Option A: Using kamal env push (Kamal 2.0+)
|
||||
kamal env push OIDC_PRIVATE_KEY="$(cat oidc_private_key.pem)"
|
||||
|
||||
# Option B: Add to .kamal/secrets
|
||||
# Add to .kamal/secrets
|
||||
echo "OIDC_PRIVATE_KEY=$(cat oidc_private_key.pem)" >> .kamal/secrets
|
||||
```
|
||||
|
||||
@@ -60,57 +57,6 @@ bin/rails runner "puts OidcJwtService.send(:private_key).present? ? 'Key loaded'
|
||||
|
||||
---
|
||||
|
||||
## Option 2: Rails Credentials (Simpler but less flexible)
|
||||
|
||||
### 1. Generate the key
|
||||
|
||||
```bash
|
||||
openssl genrsa -out oidc_private_key.pem 2048
|
||||
```
|
||||
|
||||
### 2. Add to Rails credentials
|
||||
|
||||
```bash
|
||||
EDITOR="nano" bin/rails credentials:edit
|
||||
```
|
||||
|
||||
Add this section:
|
||||
|
||||
```yaml
|
||||
oidc_private_key: |
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAyZ0qaICMiLVWSFs+ef9Xok3fzy0p6k/7D5TQzmxf7C2vQG7s
|
||||
2Odmi8iAHLoaUBaFj70qTbaconWyMr8s+ah+qZwrwolTLUe23VrceVXvInU57hBL
|
||||
...
|
||||
-----END RSA PRIVATE KEY-----
|
||||
```
|
||||
|
||||
**Important:** Use the `|` pipe character for multi-line, and indent the key content with 2 spaces.
|
||||
|
||||
### 3. Save and verify
|
||||
|
||||
```bash
|
||||
# Verify credentials file
|
||||
cat config/credentials.yml.enc # Should show encrypted data
|
||||
|
||||
# Test in console
|
||||
bin/rails runner "puts OidcJwtService.send(:private_key).present? ? 'Key loaded' : 'Key missing'"
|
||||
```
|
||||
|
||||
### 4. For deployment
|
||||
|
||||
The `config/credentials.yml.enc` file is committed to git. You need to:
|
||||
|
||||
1. **Set RAILS_MASTER_KEY** env variable in production
|
||||
2. Get the key from `config/master.key` (don't commit this!)
|
||||
|
||||
```bash
|
||||
# In Kamal
|
||||
kamal env push RAILS_MASTER_KEY="$(cat config/master.key)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comparison
|
||||
|
||||
| Feature | ENV Variable | Rails Credentials |
|
||||
@@ -145,31 +91,7 @@ kamal env push RAILS_MASTER_KEY="$(cat config/master.key)"
|
||||
|
||||
## Key Rotation (Advanced)
|
||||
|
||||
If you need to rotate keys (security incident, etc.):
|
||||
|
||||
### 1. Generate new key
|
||||
|
||||
```bash
|
||||
openssl genrsa -out oidc_private_key_new.pem 2048
|
||||
```
|
||||
|
||||
### 2. Add NEW key alongside old (dual-key setup)
|
||||
|
||||
This requires code changes to support multiple keys in JWKS. For now, rotation means:
|
||||
|
||||
**Warning:** Rotating the key will **invalidate all existing OIDC sessions**. Users will need to log in again.
|
||||
|
||||
### 3. Update OIDC_PRIVATE_KEY
|
||||
|
||||
```bash
|
||||
kamal env push OIDC_PRIVATE_KEY="$(cat oidc_private_key_new.pem)"
|
||||
```
|
||||
|
||||
### 4. Restart application
|
||||
|
||||
```bash
|
||||
kamal deploy
|
||||
```
|
||||
Todo
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user