aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/keycloak.org20
-rw-r--r--flake/terraform.nix2
-rw-r--r--terraform/admin/base.nix8
-rw-r--r--terraform/admin/default.nix1
-rw-r--r--terraform/admin/keycloak.nix162
5 files changed, 193 insertions, 0 deletions
diff --git a/docs/keycloak.org b/docs/keycloak.org
index e29350f..c8760ff 100644
--- a/docs/keycloak.org
+++ b/docs/keycloak.org
@@ -22,3 +22,23 @@ There's an admin user in 1password.
- the client ID is =forgejo=
- the client secret is in the =credentials= tab in forgejo for the client
- select =skip local 2FA=
+** Managing with terranix
+Ultimately we want to manage it with terranix.
+
+First, we need a client ID and a secret. The client can be created in the UI:
+- https://id.fcuny.net/admin/master/console/#/master/clients
+- create a new client (use =terranix= if possible, so that it's descriptive)
+- =Standard Flow Enabled= should be disabled
+- =Direct Access Grants Enabled= should be disabled
+- =Service Accounts Enabled= should be enabled
+
+The go to "Service account roles" for the newly created client, and ensure it has =admin= role (assign role -> filter by realm roles -> admin).
+
+Export the secret with =KEYCLOAK_CLIENT_SECRET=.
+
+To import resources:
+#+begin_src bash
+nix run .#tf -- import keycloak_realm.master master
+nix run .#tf -- import keycloak_user.fcuny master/d0fdbc04-8f6c-4558-8fd6-ebf7d9e23e6f
+...
+#+end_src
diff --git a/flake/terraform.nix b/flake/terraform.nix
index 23cc6d3..d593b98 100644
--- a/flake/terraform.nix
+++ b/flake/terraform.nix
@@ -31,8 +31,10 @@
p.digitalocean
p.external
p.google
+ p.keycloak
p.null
p.random
+ p.secret
];
};
};
diff --git a/terraform/admin/base.nix b/terraform/admin/base.nix
index 7221742..97cf738 100644
--- a/terraform/admin/base.nix
+++ b/terraform/admin/base.nix
@@ -11,6 +11,10 @@
prefix = "admin";
};
required_providers = {
+ secret = {
+ version = "~> 1.2.1";
+ source = "numtide/secret";
+ };
google = {
source = "hashicorp/google";
};
@@ -25,6 +29,10 @@
source = "hashicorp/random";
version = "~> 3.1";
};
+ keycloak = {
+ source = "keycloak/keycloak";
+ version = "~> 5.0";
+ };
};
};
}
diff --git a/terraform/admin/default.nix b/terraform/admin/default.nix
index 0cbbe12..0b06e25 100644
--- a/terraform/admin/default.nix
+++ b/terraform/admin/default.nix
@@ -4,6 +4,7 @@
./base.nix
./dns.nix
./droplet-proxy.nix
+ ./keycloak.nix
./variables.nix
];
}
diff --git a/terraform/admin/keycloak.nix b/terraform/admin/keycloak.nix
new file mode 100644
index 0000000..4c1af8b
--- /dev/null
+++ b/terraform/admin/keycloak.nix
@@ -0,0 +1,162 @@
+{ lib, ... }:
+let
+ mkUser =
+ {
+ enable ? true,
+ first_name,
+ last_name,
+ username,
+ email,
+ initial_password ? null,
+ }:
+ {
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+ enabled = enable;
+ inherit
+ username
+ email
+ first_name
+ last_name
+ ;
+ email_verified = true;
+
+ required_actions = [
+ "Update password"
+ "Configure OTP"
+ ];
+
+ initial_password = {
+ value = email;
+ temporary = true;
+ };
+ };
+
+in
+{
+ provider.keycloak = {
+ client_id = "terranix";
+ url = "https://id.fcuny.net";
+ realm = "master";
+ };
+
+ resource.secret_resource.keycloak_smtp_password.lifecycle.prevent_destroy = true;
+
+ resource.keycloak_realm."fcuny" = {
+ enabled = true;
+ realm = "fcuny.net";
+ display_name = "Keycloak for fcuny.net";
+ login_theme = "keycloak";
+ access_code_lifespan = "1h";
+
+ reset_password_allowed = true;
+ remember_me = true;
+ login_with_email_allowed = true;
+
+ smtp_server = {
+ from = "noreply@fcuny.net";
+ from_display_name = "fcuny.net identity services";
+ host = "smtp.fastmail.com";
+ port = 465;
+ ssl = true;
+ starttls = true;
+
+ auth = {
+ username = "franck@fcuny.net";
+ # nix run .#tf -- import secret_resource.keycloak_smtp_password SMPT_PASSWORD
+ # https://github.com/numtide/terraform-provider-secret?tab=readme-ov-file#usage
+ password = lib.tf.ref "resource.secret_resource.keycloak_smtp_password.value";
+ };
+ };
+
+ default_signature_algorithm = "RS256";
+ };
+
+ resource.keycloak_user = {
+ fcuny = mkUser {
+ username = "fcuny";
+ first_name = "Franck";
+ last_name = "Cuny";
+ email = "franck@fcuny.net";
+ };
+ };
+
+ data.keycloak_openid_client.realm_management_client = {
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+ client_id = "realm-management";
+ };
+
+ data.keycloak_role.admin = {
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+ client_id = lib.tf.ref "data.keycloak_openid_client.realm_management_client.id";
+ name = "realm-admin";
+ };
+
+ resource.keycloak_role = {
+ forgejo_admin = {
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+ client_id = lib.tf.ref "keycloak_openid_client.forgejo.id";
+ name = "Forgejo Admin";
+ description = "Forgejo's site admin";
+ };
+ };
+
+ resource.keycloak_openid_user_client_role_protocol_mapper = {
+ forgejo_role_mapper = {
+ name = "forgejo_roles_mapper";
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+ client_id = lib.tf.ref "keycloak_openid_client.forgejo.id";
+
+ claim_name = "forgejo_roles";
+ claim_value_type = "String";
+ add_to_id_token = true;
+ add_to_access_token = true;
+ multivalued = true;
+ client_id_for_role_mappings = lib.tf.ref "keycloak_openid_client.forgejo.client_id";
+ };
+ };
+
+ resource.keycloak_user_roles =
+ let
+ superadminRoles = {
+ exhaustive = false;
+
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+
+ role_ids = [
+ (lib.tf.ref "data.keycloak_role.admin.id")
+ (lib.tf.ref "keycloak_role.forgejo_admin.id")
+ ];
+ };
+ in
+ {
+ fcuny_roles = superadminRoles // {
+ user_id = lib.tf.ref "keycloak_user.fcuny.id";
+ };
+ };
+
+ resource.keycloak_openid_client = {
+ forgejo = {
+ realm_id = lib.tf.ref "keycloak_realm.fcuny.id";
+ client_id = "forgejo";
+ name = "Forgejo [fcuny.net]";
+ enabled = true;
+ access_type = "CONFIDENTIAL";
+ standard_flow_enabled = true;
+ oauth2_device_authorization_grant_enabled = true;
+ base_url = "https://code.fcuny.net";
+ description = "fcuny.net's Forgejo instance";
+ direct_access_grants_enabled = true;
+ exclude_session_state_from_auth_response = false;
+ service_accounts_enabled = false;
+ full_scope_allowed = false;
+
+ valid_redirect_uris = [
+ "https://code.fcuny.net/*"
+ ];
+
+ web_origins = [
+ "https://code.fcuny.net"
+ ];
+ };
+ };
+}