Step 4: Add Authentication

This step adds authentication capabilities to your application by creating an auth namespace, configuring user profile management, and setting up a machine user for administrative access. The authentication system integrates with your existing User type in TailorDB to provide a complete identity management solution.

What This Step Does

In this step, you:

  1. Create a Tailor Auth namespace called project-management-auth
  2. Configure user profile settings that link authentication to your TailorDB User type
  3. Map the email field as the username for authentication
  4. Map user attributes (roles) to be available for authorization decisions
  5. Create a machine user for administrative and automated operations
  6. Update the application to include the auth subgraph, enabling authentication features in your GraphQL API

Configuration Files

To follow along, review the configuration files for this step here.

auth.tf (New)

This file creates the authentication namespace and configuration:

<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_auth&quot; &quot;prj_mgmt_auth&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> var.workspace_id</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace    </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;project-management-auth&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_auth_user_profile_config&quot; &quot;user&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> var.workspace_id</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace    </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  tailordb_config </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    namespace      </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_tailordb.prj_mgmt_db.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">    type           </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_tailordb_type.user.name</span></span>
<span><span style="color: var(--shiki-color-text)">    username_field </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;email&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    attribute_map </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      roles </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;roles&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_auth_machine_user&quot; &quot;admin_machine_user&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> var.workspace_id</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace    </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  name </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;admin-machine-user&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  attribute_map </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    roles </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { string_array </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-string-expression)">&quot;admin&quot;</span><span style="color: var(--shiki-color-text)">] }</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

applications.tf (Updated)

The application configuration is updated to include authentication:

<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_application&quot; &quot;project_management&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> var.workspace_id</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  auth </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    namespace </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  name </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;project-management&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  cors </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;http://localhost:8080&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;http://localhost:8081&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">  allowed_ip_addresses </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;0.0.0.0/0&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">  subgraphs </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">    {</span></span>
<span><span style="color: var(--shiki-color-text)">      type      </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;tailordb&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">      namespace </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_tailordb.prj_mgmt_db.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    {</span></span>
<span><span style="color: var(--shiki-color-text)">      type      </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;auth&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">      namespace </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span></span>
<span><span style="color: var(--shiki-color-text)">  ]</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Key Features

User Profile Configuration

The tailor_auth_user_profile_config resource links authentication identities to your TailorDB User type:

<span><span style="color: var(--shiki-color-text)">tailordb_config </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace      </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_tailordb.prj_mgmt_db.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">  type           </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_tailordb_type.user.name</span></span>
<span><span style="color: var(--shiki-color-text)">  username_field </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;email&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  attribute_map </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    roles </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;roles&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Key configuration elements:

  • namespace: References the TailorDB namespace containing your User type
  • type: Specifies which TailorDB type represents user profiles
  • username_field: Maps the email field as the unique identifier for authentication
  • attribute_map: Maps TailorDB fields to authentication attributes that will be available for authorization decisions

When a user authenticates, the auth service will automatically create or update a corresponding User record in TailorDB. The roles field will be accessible in permission policies and authorization logic.

Machine User

The tailor_auth_machine_user resource creates a service account for administrative operations:

<span><span style="color: var(--shiki-token-function)">resource</span><span style="color: var(--shiki-color-text)"> &quot;tailor_auth_machine_user&quot; &quot;admin_machine_user&quot; {</span></span>
<span><span style="color: var(--shiki-color-text)">  workspace_id </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> var.workspace_id</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace    </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  name </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;admin-machine-user&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  attribute_map </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    roles </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> { string_array </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> [</span><span style="color: var(--shiki-token-string-expression)">&quot;admin&quot;</span><span style="color: var(--shiki-color-text)">] }</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Machine users are useful for:

  • Automated background processes
  • System-level operations that don't belong to a specific user
  • Pipeline resolvers that need elevated permissions
  • Integration with external systems

The attribute_map assigns the "admin" role to the machine user, making it available for authorization decisions in permission policies and pipeline resolvers.

Application Auth Integration

The application configuration now includes two important additions:

  1. Auth block: Links the application to the auth namespace
<span><span style="color: var(--shiki-color-text)">auth </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
  1. Auth subgraph: Adds the me query to the GraphQL API
<span><span style="color: var(--shiki-color-text)">{</span></span>
<span><span style="color: var(--shiki-color-text)">  type      </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;auth&quot;</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> tailor_auth.prj_mgmt_auth.namespace</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Adding the auth subgraph exposes the me query in your application's merged GraphQL API. The me query returns the currently authenticated user's information (sourced from your TailorDB User type). Authentication flows (sign-in, registration, and token issuance) are handled by the auth service and are not exposed as GraphQL operations.

Expected Outcome

After applying this configuration with terraform apply, you should see:

  1. An auth namespace named project-management-auth created in your workspace
  2. User profile configuration linking authentication to the TailorDB User type
  3. A machine user named admin-machine-user available for system operations
  4. The application updated to include auth capabilities
  5. The me query available in your GraphQL API for retrieving authenticated user information

You can verify the setup by:

  • Viewing the auth namespace in the Tailor Console
  • Checking that the user profile configuration is active
  • Confirming the machine user appears in the auth namespace

Next step

Continue to Step 5: Add Pipeline.