Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ The following options can be configured on the server:
storage.session.redis.sentinel.username Username for authenticating to Redis Sentinels.
storage.session.redis.tls.truststorefile PEM file containing the trusted CA certificate(s) for authenticating remote Redis session servers. Can only be used when connecting over TLS (use 'rediss://' as scheme in address).
storage.sql.connection Connection string for the SQL database. If not set it, defaults to a SQLite database stored inside the configured data directory. Note: using SQLite is not recommended in production environments. If using SQLite anyways, remember to enable foreign keys ('_foreign_keys=on') and the write-ahead-log ('_journal_mode=WAL').
storage.sql.rdsiam.enabled false Enable AWS RDS IAM authentication for the SQL database connection. When enabled, the node will use temporary IAM tokens instead of passwords. Requires the connection string to be a PostgreSQL or MySQL RDS endpoint without a password.
storage.sql.rdsiam.region AWS region where the RDS instance is located (e.g., 'us-east-1). Required when RDS IAM authentication is enabled.
storage.sql.rdsiam.dbuser Database username for IAM authentication. If not specified, the username from the connection string will be used. The database user must be created with IAM authentication enabled.
storage.sql.rdsiam.tokenrefreshinterval 14m0s Interval at which to refresh the IAM authentication token. RDS tokens are valid for 15 minutes, so the default is 14 minutes to ensure tokens are refreshed before expiry. Specified as Golang duration (e.g. 10m, 1h).
**policy**
policy.directory ./config/policy Directory to read policy files from. Policy files are JSON files that contain a scope to PresentationDefinition mapping.
======================================== =================================================================================================================================================================================================================================================================================================================================================================================================================================================================== ============================================================================================================================================================================================================================================================================================================================================
Expand Down
36 changes: 36 additions & 0 deletions docs/pages/deployment/storage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,42 @@ Refer to the documentation of the driver for the database you are using for the
Usage of SQLite is not recommended for production environments.
Connections to a SQLite DB are restricted to 1, which will lead to severe performance reduction.

AWS RDS IAM authentication
==========================

Nuts supports AWS RDS IAM database authentication for SQL storage.
This replaces static database passwords with short-lived IAM auth tokens generated by the AWS SDK.

Support scope:

- Supported SQL connection schemes: ``postgres://`` and ``mysql://``.
- Not supported for RDS IAM: ``sqlite:``, ``sqlserver://`` and ``azuresql://``.
- If ``storage.sql.rdsiam.dbuser`` is set, that database user is used; otherwise the username from ``storage.sql.connection`` is used.

Configuration in the Nuts node:

.. code-block:: yaml

storage:
sql:
connection: "postgres://dbuser@mydb.eu-west-1.rds.amazonaws.com:5432/nuts?sslmode=require"
rdsiam:
enabled: true
region: "eu-west-1"
dbuser: "dbuser" # optional

Configuration keys:

- ``storage.sql.rdsiam.enabled``: enables RDS IAM authentication.
- ``storage.sql.rdsiam.region``: AWS region of the RDS instance.
- ``storage.sql.rdsiam.dbuser``: optional IAM-enabled DB user to use.
- ``storage.sql.rdsiam.tokenrefreshinterval``: optional token refresh interval, defaults to ``14m``.

When enabled, the node automatically refreshes IAM tokens and uses new tokens for fresh SQL connections.

For generic AWS RDS IAM setup (enabling IAM DB auth on the instance, IAM policies, and DB user grants),
refer to the AWS documentation: `IAM database authentication for MariaDB, MySQL, and PostgreSQL <https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html>`_.

Session storage
***************

Expand Down
15 changes: 15 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ require (
)

require (
github.com/aws/aws-sdk-go-v2/config v1.32.7
github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.6.17
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
github.com/daangn/minimemcached v1.2.0
github.com/eko/gocache/lib/v4 v4.2.3
Expand All @@ -219,6 +221,19 @@ require (
)

require (
github.com/aws/aws-sdk-go-v2 v1.41.1 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.19.7 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect
github.com/aws/smithy-go v1.24.0 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
Expand Down
30 changes: 30 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,36 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7D
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
github.com/avast/retry-go/v4 v4.7.0 h1:yjDs35SlGvKwRNSykujfjdMxMhMQQM0TnIjJaHB+Zio=
github.com/avast/retry-go/v4 v4.7.0/go.mod h1:ZMPDa3sY2bKgpLtap9JRUgk2yTAba7cgiFhqxY2Sg6Q=
github.com/aws/aws-sdk-go-v2 v1.41.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU=
github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2/config v1.32.7 h1:vxUyWGUwmkQ2g19n7JY/9YL8MfAIl7bTesIUykECXmY=
github.com/aws/aws-sdk-go-v2/config v1.32.7/go.mod h1:2/Qm5vKUU/r7Y+zUk/Ptt2MDAEKAfUtKc1+3U1Mo3oY=
github.com/aws/aws-sdk-go-v2/credentials v1.19.7 h1:tHK47VqqtJxOymRrNtUXN5SP/zUTvZKeLx4tH6PGQc8=
github.com/aws/aws-sdk-go-v2/credentials v1.19.7/go.mod h1:qOZk8sPDrxhf+4Wf4oT2urYJrYt3RejHSzgAquYeppw=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA=
github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.6.17 h1:BTFAHrUqHRo9KRVXojX/uU/ht9tyYH2TN0NfPiyLfqA=
github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.6.17/go.mod h1:8Xhnm3tJUGk9ernojWk4VOgEsPhDkeNOrY+IVRL6eqY=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y=
github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 h1:gd84Omyu9JLriJVCbGApcLzVR3XtmC4ZDPcAI6Ftvds=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ=
github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ=
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down
11 changes: 11 additions & 0 deletions storage/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ func FlagSet() *pflag.FlagSet {
"If not set it, defaults to a SQLite database stored inside the configured data directory. "+
"Note: using SQLite is not recommended in production environments. "+
"If using SQLite anyways, remember to enable foreign keys ('_foreign_keys=on') and the write-ahead-log ('_journal_mode=WAL').")
flagSet.Bool("storage.sql.rdsiam.enabled", defs.SQL.RDSIAM.Enabled, "Enable AWS RDS IAM authentication for the SQL database connection. "+
"When enabled, the node will use temporary IAM tokens instead of passwords. "+
"Requires the connection string to be a PostgreSQL or MySQL RDS endpoint without a password.")
flagSet.String("storage.sql.rdsiam.region", defs.SQL.RDSIAM.Region, "AWS region where the RDS instance is located (e.g., 'us-east-1). "+
"Required when RDS IAM authentication is enabled.")
flagSet.String("storage.sql.rdsiam.dbuser", defs.SQL.RDSIAM.DBUser, "Database username for IAM authentication. "+
"If not specified, the username from the connection string will be used. "+
"The database user must be created with IAM authentication enabled.")
flagSet.Duration("storage.sql.rdsiam.tokenrefreshinterval", defs.SQL.RDSIAM.TokenRefreshInterval, "Interval at which to refresh the IAM authentication token. "+
"RDS tokens are valid for 15 minutes, so set this to ensure tokens are refreshed before expiry. "+
"Specified as Golang duration (e.g. 10m, 1h).")

// session
flagSet.StringSlice("storage.session.memcached.address", defs.Session.Memcached.Address, "List of Memcached server addresses. These can be a simple 'host:port' or a Memcached connection URL with scheme, auth and other options.")
Expand Down
27 changes: 26 additions & 1 deletion storage/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package storage

import "time"

// Config specifies config for the storage engine.
type Config struct {
BBolt BBoltConfig `koanf:"bbolt"`
Expand All @@ -28,14 +30,37 @@ type Config struct {

// DefaultConfig returns the default configuration for the module.
func DefaultConfig() Config {
return Config{}
return Config{
SQL: SQLConfig{
RDSIAM: RDSIAMConfig{
TokenRefreshInterval: 14 * time.Minute,
},
},
}
}

// SQLConfig specifies config for the SQL storage engine.
type SQLConfig struct {
// ConnectionString is the connection string for the SQL database.
// This string may contain secrets (user:password), so should never be logged.
ConnectionString string `koanf:"connection"`
// RDSIAM specifies AWS RDS IAM authentication configuration.
RDSIAM RDSIAMConfig `koanf:"rdsiam"`
}

// RDSIAMConfig specifies config for AWS RDS IAM authentication.
type RDSIAMConfig struct {
// Enabled determines whether to use AWS IAM authentication for RDS.
Enabled bool `koanf:"enabled"`
// Region is the AWS region where the RDS instance is located.
// If not specified, it will be loaded from the AWS SDK default configuration.
Region string `koanf:"region"`
// DBUser is the database user for IAM authentication.
// If not specified, the user from the connection string will be used.
DBUser string `koanf:"dbuser"`
// TokenRefreshInterval is how often to refresh the IAM token (default: 14 minutes).
// RDS tokens are valid for 15 minutes, so we refresh before expiry.
TokenRefreshInterval time.Duration `koanf:"tokenrefreshinterval"`
}

// SessionConfig specifies config for the session storage engine.
Expand Down
Loading