Rails Credentials e Secrets nel 2026: Gestione Sicura delle Variabili d'Ambiente
Guida completa alla gestione sicura di credentials e secrets in Ruby on Rails con credenziali crittografate, configurazioni per ambiente e best practice per la produzione.

La gestione sicura di secrets e variabili d'ambiente rappresenta uno degli aspetti più critici di qualsiasi applicazione Rails. Una chiave API compromessa o una password del database esposta può avere conseguenze devastanti. Rails offre con il sistema Credentials una soluzione elegante che unisce sicurezza e facilità d'uso per gli sviluppatori.
Rails 8 ha ulteriormente migliorato il sistema Credentials offrendo supporto nativo per ambienti multipli senza gem aggiuntive. Per i progetti esistenti con Rails 7.1+, l'aggiornamento risulta semplice.
Perché utilizzare il sistema Credentials di Rails?
Il metodo tradizionale di memorizzazione dei secrets nelle variabili d'ambiente o nei file .env comporta diversi rischi. Le variabili d'ambiente possono comparire nei log, vengono talvolta incorporate accidentalmente nelle immagini dei container o finiscono nei crash report. Il sistema Credentials di Rails risolve questi problemi attraverso la crittografia a livello di filesystem.
# Approccio tradizionale con variabili d'ambiente - vulnerabile ai leak
config.secret_key_base = ENV['SECRET_KEY_BASE']
config.api_key = ENV['EXTERNAL_API_KEY']
# Rails Credentials - crittografato e sicuro
config.secret_key_base = Rails.application.credentials.secret_key_base
config.api_key = Rails.application.credentials.dig(:external_service, :api_key)Le credentials vengono crittografate con una master key che non viene mai inserita nel repository. Anche se un attaccante ottenesse accesso al file crittografato, i secrets sarebbero inutili senza la master key.
Creazione e modifica delle Credentials
Rails fornisce un editor integrato per la gestione delle credentials. Il comando decrittografa temporaneamente il file, apre l'editor e lo crittografa nuovamente dopo il salvataggio.
# Modificare le credentials con l'editor predefinito
RAILS_MASTER_KEY=your_master_key rails credentials:edit
# Utilizzare un editor specifico
EDITOR="code --wait" rails credentials:edit
# Modificare credentials specifiche per ambiente (Rails 7.1+)
rails credentials:edit --environment production
rails credentials:edit --environment stagingLa struttura del file credentials segue il formato YAML e supporta livelli di annidamento arbitrari:
# config/credentials.yml.enc (decrittografato)
secret_key_base: a1b2c3d4e5f6g7h8i9j0...
aws:
access_key_id: AKIAIOSFODNN7EXAMPLE
secret_access_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
region: eu-central-1
bucket: my-production-bucket
stripe:
publishable_key: pk_live_...
secret_key: sk_live_...
webhook_secret: whsec_...
database:
primary:
host: db.example.com
username: app_user
password: secure_password_123
replica:
host: db-replica.example.com
username: readonly_user
password: readonly_password_456
redis:
url: redis://:password@redis.example.com:6379/0
smtp:
address: smtp.sendgrid.net
port: 587
user_name: apikey
password: SG.xxxxxCredentials specifiche per ambiente
Le applicazioni Rails moderne richiedono credentials differenti per Development, Staging e Production. Rails supporta questa esigenza attraverso file crittografati separati per ogni ambiente.
# Struttura nella directory config
config/
├── credentials.yml.enc # Fallback per tutti gli ambienti
├── credentials/
│ ├── development.yml.enc # Solo per Development
│ ├── development.key
│ ├── staging.yml.enc # Solo per Staging
│ ├── staging.key
│ ├── production.yml.enc # Solo per Production
│ └── production.key
└── master.key # Chiave di fallbackL'accesso alle credentials avviene in modo identico; Rails seleziona automaticamente il file corretto in base a RAILS_ENV:
# config/database.yml
production:
primary:
adapter: postgresql
host: <%= Rails.application.credentials.dig(:database, :primary, :host) %>
username: <%= Rails.application.credentials.dig(:database, :primary, :username) %>
password: <%= Rails.application.credentials.dig(:database, :primary, :password) %>
database: myapp_production
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>Utilizzo delle Credentials nell'applicazione
L'accesso alle credentials è possibile in diversi punti dell'applicazione. Il metodo dig offre un accesso sicuro ai valori annidati e restituisce nil se un percorso non esiste.
# Negli initializer
# config/initializers/stripe.rb
Stripe.api_key = Rails.application.credentials.dig(:stripe, :secret_key)
# Nei modelli o servizi
class PaymentService
def initialize
@api_key = Rails.application.credentials.dig(:payment_gateway, :api_key)
@merchant_id = Rails.application.credentials.dig(:payment_gateway, :merchant_id)
end
def process_payment(amount, token)
# Utilizzo sicuro delle credentials
client = PaymentClient.new(
api_key: @api_key,
merchant_id: @merchant_id
)
client.charge(amount: amount, source: token)
end
end
# Nei controller (quando necessario)
class WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def stripe
payload = request.body.read
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
webhook_secret = Rails.application.credentials.dig(:stripe, :webhook_secret)
begin
event = Stripe::Webhook.construct_event(payload, sig_header, webhook_secret)
handle_event(event)
head :ok
rescue Stripe::SignatureVerificationError
head :bad_request
end
end
endGestione della Master Key in produzione
La master key rappresenta la parte più critica del sistema. Non deve mai essere inserita nel repository e deve essere trasmessa in modo sicuro all'ambiente di produzione.
# Opzione 1: Variabile d'ambiente (consigliata per container)
export RAILS_MASTER_KEY="your-master-key-here"
# Opzione 2: File sul server (per deployment basati su VM)
echo "your-master-key-here" > /var/www/myapp/shared/config/master.key
chmod 600 /var/www/myapp/shared/config/master.key
# Opzione 3: Integrazione con Secret Manager (AWS, GCP, Azure)
# In un initializer o prima dell'avvio di Rails
export RAILS_MASTER_KEY=$(aws secretsmanager get-secret-value \
--secret-id rails/production/master-key \
--query SecretString --output text)Per l'orchestrazione di container come Kubernetes, si consiglia l'utilizzo dei Secrets:
# kubernetes/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: rails-credentials
namespace: production
type: Opaque
stringData:
RAILS_MASTER_KEY: "your-master-key-here"
---
# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: rails-app
spec:
template:
spec:
containers:
- name: rails
image: myapp:latest
envFrom:
- secretRef:
name: rails-credentialsValidazione e test delle Credentials
Per assicurarsi che tutte le credentials richieste siano presenti, si consiglia una validazione all'avvio dell'applicazione:
# config/initializers/credentials_validator.rb
class CredentialsValidator
REQUIRED_CREDENTIALS = [
[:secret_key_base],
[:database, :primary, :password],
[:stripe, :secret_key],
[:stripe, :webhook_secret],
[:aws, :access_key_id],
[:aws, :secret_access_key]
].freeze
def self.validate!
return if Rails.env.test?
missing = REQUIRED_CREDENTIALS.select do |path|
Rails.application.credentials.dig(*path).blank?
end
if missing.any?
missing_paths = missing.map { |p| p.join('.') }.join(', ')
raise "Missing required credentials: #{missing_paths}"
end
end
end
Rails.application.config.after_initialize do
CredentialsValidator.validate!
endNei test, le credentials possono essere simulate per non richiedere secrets reali:
# spec/rails_helper.rb
RSpec.configure do |config|
config.before(:each) do
allow(Rails.application.credentials).to receive(:dig)
.with(:stripe, :secret_key).and_return('sk_test_mock')
allow(Rails.application.credentials).to receive(:dig)
.with(:stripe, :webhook_secret).and_return('whsec_mock')
end
end
# Oppure con un set di test credentials
# spec/support/test_credentials.rb
module TestCredentials
def self.configure!
credentials = ActiveSupport::OrderedOptions.new
credentials.stripe = ActiveSupport::OrderedOptions.new
credentials.stripe.secret_key = 'sk_test_mock'
credentials.stripe.webhook_secret = 'whsec_mock'
allow(Rails.application).to receive(:credentials).and_return(credentials)
end
endPronto a superare i tuoi colloqui su Ruby on Rails?
Pratica con i nostri simulatori interattivi, flashcards e test tecnici.
Migrazione dalle variabili d'ambiente alle Credentials
Per i progetti esistenti che ancora utilizzano variabili d'ambiente, si raccomanda una migrazione graduale:
# Fase di transizione: supporto per entrambi i metodi
# config/initializers/external_services.rb
module ExternalServices
class << self
def stripe_key
# Le credentials hanno priorità, fallback su ENV
Rails.application.credentials.dig(:stripe, :secret_key) ||
ENV['STRIPE_SECRET_KEY']
end
def aws_access_key
Rails.application.credentials.dig(:aws, :access_key_id) ||
ENV['AWS_ACCESS_KEY_ID']
end
end
end
# Dopo la migrazione completa: solo credentials in modo rigoroso
module ExternalServices
class << self
def stripe_key
Rails.application.credentials.dig(:stripe, :secret_key) ||
raise('Stripe secret key not configured in credentials')
end
end
endBest practice di sicurezza
L'implementazione di un sistema credentials robusto richiede l'attenzione a diversi aspetti di sicurezza:
# Mai stampare credentials nei log
# config/initializers/filter_parameters.rb
Rails.application.config.filter_parameters += [
:password, :secret, :token, :_key, :crypt, :salt,
:certificate, :otp, :ssn, :api_key, :access_key,
:credentials, :master_key
]
# Gestione sicura degli errori senza leak di secrets
class ApiClient
def initialize
@api_key = Rails.application.credentials.dig(:api, :key)
end
def fetch_data
response = HTTParty.get(
'https://api.example.com/data',
headers: { 'Authorization' => "Bearer #{@api_key}" }
)
response.parsed_response
rescue StandardError => e
# Mai registrare la chiave API nell'errore
Rails.logger.error("API request failed: #{e.message}")
raise ApiError, 'External service unavailable'
end
endImplementazione della rotazione delle chiavi
La rotazione regolare delle chiavi aumenta la sicurezza. Rails supporta questa pratica attraverso la validità simultanea di più chiavi:
# config/credentials.yml.enc
aws:
access_key_id: NEW_KEY_ID
secret_access_key: NEW_SECRET
# Vecchia chiave per fase di transizione
legacy_access_key_id: OLD_KEY_ID
legacy_secret_access_key: OLD_SECRET
# Service con logica di fallback
class S3Service
def client
@client ||= begin
Aws::S3::Client.new(
access_key_id: credentials(:access_key_id),
secret_access_key: credentials(:secret_access_key),
region: Rails.application.credentials.dig(:aws, :region)
)
end
end
private
def credentials(key)
Rails.application.credentials.dig(:aws, key) ||
Rails.application.credentials.dig(:aws, :"legacy_#{key}")
end
endConclusione
Il sistema Credentials di Rails offre una soluzione sicura ed elegante per la gestione di dati di configurazione sensibili. Attraverso l'utilizzo di file crittografati, credentials specifiche per ambiente e una gestione oculata delle chiavi, i secrets possono essere protetti efficacemente. La migrazione dalle classiche variabili d'ambiente alle Rails Credentials riduce significativamente il rischio di leak dei secrets e migliora contemporaneamente l'ergonomia dello sviluppatore grazie a un punto centrale di configurazione.
Tag
Condividi
Articoli correlati

ActiveRecord: risolvere i problemi di query N+1 in Ruby on Rails
Guida completa per individuare e risolvere le query N+1 in Rails con ActiveRecord. Padroneggia includes, preload, eager_load e gli strumenti di rilevamento automatico.

Domande colloquio Ruby on Rails: Top 25 nel 2026
Le 25 domande più frequenti per i colloqui Ruby on Rails. Architettura MVC, Active Record, migration, testing RSpec, API REST con risposte dettagliate ed esempi di codice.

Ruby on Rails 7: Hotwire e Turbo per Applicazioni Reattive
Guida completa a Hotwire e Turbo in Rails 7. Costruire applicazioni reattive senza scrivere JavaScript con Turbo Drive, Frames e Streams.