#!/bin/bash # ============================================================================= # Gitea OAuth Application Setup for Authentik # ============================================================================= # Creates OAuth2 provider and application in Authentik for Gitea # Outputs credentials for manual Gitea UI configuration # # Generated by ansible - do not edit manually # ============================================================================= set -e AUTHENTIK_DOMAIN="{{ authentik_domain }}" GITEA_DOMAIN="{{ gitea_domain }}" CLIENT_ID="{{ gitea_oauth_client_id }}" PROVIDER_NAME="{{ gitea_oauth_provider_name }}" OUTPUT_FILE="/tmp/gitea-oauth-credentials.json" # Bootstrap token from Authentik API_TOKEN="{{ vault_authentik_bootstrap_token }}" echo "============================================" echo "Gitea OAuth Application Setup" echo "============================================" echo "" echo "Authentik: https://${AUTHENTIK_DOMAIN}" echo "Gitea: https://${GITEA_DOMAIN}" echo "" # ----------------------------------------------------------------------------- # Test API access # ----------------------------------------------------------------------------- echo "Testing Authentik API access..." HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ "https://${AUTHENTIK_DOMAIN}/api/v3/core/brands/" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") if [ "$HTTP_CODE" != "200" ]; then echo "ERROR: API authentication failed (HTTP $HTTP_CODE)" echo "Check that vault_authentik_bootstrap_token is correct" exit 1 fi echo "Authentik API ready!" echo "" # ----------------------------------------------------------------------------- # Get authorization flow PK # ----------------------------------------------------------------------------- echo "Finding authorization flow..." AUTH_FLOW_RESPONSE=$(curl -s \ "https://${AUTHENTIK_DOMAIN}/api/v3/flows/instances/?designation=authorization" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") AUTH_FLOW_PK=$(echo "$AUTH_FLOW_RESPONSE" | jq -r '.results[0].pk') echo "Authorization flow: $AUTH_FLOW_PK" # ----------------------------------------------------------------------------- # Get invalidation flow PK # ----------------------------------------------------------------------------- echo "Finding invalidation flow..." INVALID_FLOW_RESPONSE=$(curl -s \ "https://${AUTHENTIK_DOMAIN}/api/v3/flows/instances/?designation=invalidation" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") INVALID_FLOW_PK=$(echo "$INVALID_FLOW_RESPONSE" | jq -r '.results[0].pk') echo "Invalidation flow: $INVALID_FLOW_PK" # ----------------------------------------------------------------------------- # Get signing certificate # ----------------------------------------------------------------------------- echo "Finding signing certificate..." CERT_RESPONSE=$(curl -s \ "https://${AUTHENTIK_DOMAIN}/api/v3/crypto/certificatekeypairs/" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") SIGNING_KEY_PK=$(echo "$CERT_RESPONSE" | jq -r '.results[0].pk') echo "Signing key: $SIGNING_KEY_PK" # ----------------------------------------------------------------------------- # Get scope mappings # ----------------------------------------------------------------------------- echo "Getting scope mappings..." SCOPE_MAPPINGS=$(curl -s \ "https://${AUTHENTIK_DOMAIN}/api/v3/propertymappings/provider/scope/" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") OPENID_PK=$(echo "$SCOPE_MAPPINGS" | jq -r '.results[] | select(.scope_name=="openid") | .pk') PROFILE_PK=$(echo "$SCOPE_MAPPINGS" | jq -r '.results[] | select(.scope_name=="profile") | .pk') EMAIL_PK=$(echo "$SCOPE_MAPPINGS" | jq -r '.results[] | select(.scope_name=="email") | .pk') echo "Scopes: openid=$OPENID_PK, profile=$PROFILE_PK, email=$EMAIL_PK" echo "" # ----------------------------------------------------------------------------- # Check if provider already exists # ----------------------------------------------------------------------------- echo "Checking for existing Gitea provider..." EXISTING_PROVIDER=$(curl -s \ "https://${AUTHENTIK_DOMAIN}/api/v3/providers/oauth2/?name=Gitea" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") EXISTING_PK=$(echo "$EXISTING_PROVIDER" | jq -r '.results[0].pk // empty') if [ -n "$EXISTING_PK" ] && [ "$EXISTING_PK" != "null" ]; then echo "Provider already exists (PK: $EXISTING_PK), updating..." # Update existing provider PROVIDER_RESPONSE=$(curl -s -X PATCH \ "https://${AUTHENTIK_DOMAIN}/api/v3/providers/oauth2/${EXISTING_PK}/" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d "{ \"redirect_uris\": [ {\"matching_mode\": \"strict\", \"url\": \"https://${GITEA_DOMAIN}/user/oauth2/${PROVIDER_NAME}/callback\"} ] }") PROVIDER_PK="$EXISTING_PK" CLIENT_SECRET=$(echo "$EXISTING_PROVIDER" | jq -r '.results[0].client_secret // empty') else # ----------------------------------------------------------------------------- # Create OAuth2 Provider (confidential client for Gitea) # ----------------------------------------------------------------------------- echo "Creating Gitea OAuth2 Provider..." PROVIDER_RESPONSE=$(curl -s -X POST \ "https://${AUTHENTIK_DOMAIN}/api/v3/providers/oauth2/" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"Gitea\", \"authorization_flow\": \"${AUTH_FLOW_PK}\", \"invalidation_flow\": \"${INVALID_FLOW_PK}\", \"signing_key\": \"${SIGNING_KEY_PK}\", \"client_type\": \"confidential\", \"client_id\": \"${CLIENT_ID}\", \"redirect_uris\": [ {\"matching_mode\": \"strict\", \"url\": \"https://${GITEA_DOMAIN}/user/oauth2/${PROVIDER_NAME}/callback\"} ], \"access_code_validity\": \"minutes=10\", \"access_token_validity\": \"hours=1\", \"refresh_token_validity\": \"days=30\", \"property_mappings\": [\"${OPENID_PK}\", \"${PROFILE_PK}\", \"${EMAIL_PK}\"], \"sub_mode\": \"user_email\", \"include_claims_in_id_token\": true, \"issuer_mode\": \"per_provider\" }") PROVIDER_PK=$(echo "$PROVIDER_RESPONSE" | jq -r '.pk // empty') CLIENT_SECRET=$(echo "$PROVIDER_RESPONSE" | jq -r '.client_secret // empty') if [ -z "$PROVIDER_PK" ] || [ "$PROVIDER_PK" = "null" ]; then echo "ERROR: Failed to create provider" echo "$PROVIDER_RESPONSE" | jq . exit 1 fi fi echo "Provider PK: $PROVIDER_PK" echo "" # ----------------------------------------------------------------------------- # Check if application already exists # ----------------------------------------------------------------------------- echo "Checking for existing Gitea application..." EXISTING_APP=$(curl -s \ "https://${AUTHENTIK_DOMAIN}/api/v3/core/applications/?slug=gitea" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json") EXISTING_APP_SLUG=$(echo "$EXISTING_APP" | jq -r '.results[0].slug // empty') if [ -z "$EXISTING_APP_SLUG" ] || [ "$EXISTING_APP_SLUG" = "null" ]; then # ----------------------------------------------------------------------------- # Create Application # ----------------------------------------------------------------------------- echo "Creating Gitea Application..." APP_RESPONSE=$(curl -s -X POST \ "https://${AUTHENTIK_DOMAIN}/api/v3/core/applications/" \ -H "Authorization: Bearer ${API_TOKEN}" \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"Gitea\", \"slug\": \"gitea\", \"provider\": ${PROVIDER_PK}, \"meta_launch_url\": \"https://${GITEA_DOMAIN}\", \"open_in_new_tab\": false }") APP_SLUG=$(echo "$APP_RESPONSE" | jq -r '.slug // empty') if [ -z "$APP_SLUG" ] || [ "$APP_SLUG" = "null" ]; then echo "WARNING: Failed to create application (may already exist)" else echo "Application created: $APP_SLUG" fi else echo "Application already exists: $EXISTING_APP_SLUG" fi echo "" # ----------------------------------------------------------------------------- # Output credentials # ----------------------------------------------------------------------------- cat > "$OUTPUT_FILE" << EOF { "client_id": "${CLIENT_ID}", "client_secret": "${CLIENT_SECRET}", "auto_discover_url": "https://${AUTHENTIK_DOMAIN}/application/o/gitea/.well-known/openid-configuration", "scopes": "email profile", "provider_name": "${PROVIDER_NAME}" } EOF echo "============================================" echo "OAuth Setup Complete!" echo "============================================" echo "" echo "Credentials saved to: ${OUTPUT_FILE}" echo "" echo "========================================" echo "MANUAL CONFIGURATION REQUIRED IN GITEA" echo "========================================" echo "" echo "1. Log into Gitea as admin:" echo " https://${GITEA_DOMAIN}/user/login" echo "" echo "2. Navigate to:" echo " Site Administration -> Authentication Sources -> Add" echo "" echo "3. Fill in the form:" echo " Authentication Type: OAuth2" echo " Authentication Name: ${PROVIDER_NAME}" echo " OAuth2 Provider: OpenID Connect" echo " Client ID: ${CLIENT_ID}" echo " Client Secret: ${CLIENT_SECRET}" echo " OpenID Connect Auto Discovery URL:" echo " https://${AUTHENTIK_DOMAIN}/application/o/gitea/.well-known/openid-configuration" echo " Additional Scopes: email profile" echo "" echo "4. Click 'Add Authentication Source'" echo "" echo "5. Test by logging out and clicking 'Sign in with ${PROVIDER_NAME}'" echo "" echo "========================================" echo "" echo "Credentials JSON:" cat "$OUTPUT_FILE" echo ""