Environment Realm
The environment realm is the outermost authentication entry point in Gauze. It is responsible for:
- Creating the initial environment session.
- Recording authentication progress in session data.
- Returning a proxy session once the sign-in requirements are satisfied.
- Minting realm-specific JWTs, such as
systemordatabaseJWTs, from that proxy session.
At a high level, the flow is:
- Call
mutation.environment.enter_sessionto create an environment session. - Complete the required authentication steps in the
environmentrealm. - Call
mutation.environment.sign_into exchange the environment session for a proxy session. - Use the proxy session JWT to call
mutation.realm.system.enter_sessionor another realm-specificenter_sessionmutation. - Use the returned realm JWT against
/system/graphql,/database/graphql, or another target realm endpoint.
Environment Session to System Session
The environment schema exposes three top-level mutation groups:
mutation.agentfor agent-specific authentication steps.mutation.environmentfor sign-in, sign-out, sign-up, and proxy-session lifecycle operations.mutation.realmfor entering and exiting target realm sessions.
In a generated project, these mutations are exposed through ${project_dir}/environment/interfaces/graphql/schema.js and the modules it imports.
Step 1: Create an Environment Session
Call environment.enter_session against /environment/graphql without an existing application session:
mutation EnterEnvironmentSession {
environment {
enter_session(proxy: null) {
gauze__session__id
gauze__session__realm
gauze__session__kind
gauze__session__agent_id
gauze__session__agent_type
gauze__session__value
}
}
}The returned gauze__session__value is the environment session JWT. Use it in the Authorization: Bearer <token> header for the authentication-step mutations that follow.
Step 2: Complete the Required Authentication Steps
The default project configuration requires these proxy authentication steps before environment.sign_in succeeds:
steps.person.assert.email.successsteps.account.verify.password.success
Those requirements are defined in ${project_dir}/gauze.js under authentication.proxy.
The currently implemented example sequence is:
mutation AssertEmail {
agent {
person {
assert {
email(
agent_person: {
gauze__agent_person__email: "user@example.com"
}
) {
success
}
}
}
}
}mutation VerifyPassword {
agent {
account {
verify {
password(
agent_account: {
gauze__agent_account__password: "correct horse battery staple"
}
) {
success
}
}
}
}
}These mutations run against /environment/graphql while you are still using an environment session.
person.request.email and person.verify.email exist in the environment GraphQL surface, but they are currently placeholders rather than a completed email-code flow. The supported sign-in example today is the combination of person.assert.email and account.verify.password.
Step 3: Exchange the Environment Session for a Proxy Session
Once the required steps are complete, call environment.sign_in:
mutation SignIn {
environment {
sign_in {
gauze__session__id
gauze__session__realm
gauze__session__agent_id
gauze__session__agent_type
gauze__session__value
}
}
}The returned gauze__session__value is the proxy session JWT. Use it as the bearer token for subsequent environment realm requests that require a proxy session.
Step 4: Mint a System JWT from the Proxy Session
With the proxy JWT in the Authorization header, call realm.system.enter_session:
mutation EnterSystemSession {
realm {
system {
enter_session(
proxy: {
gauze__proxy__agent_id: "60850dda-0340-49d1-a378-f7313ada2eee"
gauze__proxy__agent_type: "gauze__agent_user"
}
) {
gauze__session__id
gauze__session__realm
gauze__session__agent_id
gauze__session__agent_type
gauze__session__value
}
}
}
}The returned gauze__session__value is the JWT for the system realm. Use that token in the Authorization: Bearer <token> header when sending requests to /system/graphql.
Optional: Inspect Available Proxies Before Entering a Realm
If you need to inspect which target agents are available from the current proxy session, query proxy on /environment/graphql:
query AvailableProxies {
proxy {
gauze__proxy__id
gauze__proxy__agent_id
gauze__proxy__agent_type
gauze__proxy__root_id
gauze__proxy__realms
}
}The realm entry helper checks that:
- The current session is a proxy session.
- The target proxy exists under the current proxy root.
- The target proxy allows the requested realm in
gauze__proxy__realms. - The project's configured authentication requirements for that realm and agent type are satisfied.
Those checks are part of the environment realm session-entry logic in ${project_dir}/environment/.
JWT Audience and Realm Mapping
Each realm-specific enter_session controller signs a JWT with the target realm audience. In a generated project, that logic lives under ${project_dir}/environment/controllers/realms/. For example:
${project_dir}/environment/controllers/realms/system.jssigns asystemJWT.${project_dir}/environment/controllers/realms/database.jssigns adatabaseJWT.${project_dir}/environment/controllers/realms/kernel.jssigns akernelJWT.
The signing functions live in ${project_dir}/environment/authentication.js. The relevant audience values are:
environmentsystemdatabasekernel
Extending the Environment Realm
You can expand the authentication and authorization surface by defining new GraphQL methods in the environment realm.
Add a New GraphQL Method
In a generated project, environment mutations are organized by concern:
- Add sign-in or sign-out style methods to
${project_dir}/environment/interfaces/graphql/mutations/environment.js. - Add target-realm session methods to
${project_dir}/environment/interfaces/graphql/mutations/realm.jsand the files under${project_dir}/environment/interfaces/graphql/mutations/realms/. - Add agent-specific authentication steps to the files under
${project_dir}/environment/interfaces/graphql/mutations/agents/.
For a new method, the usual flow is:
- Define the GraphQL field in the appropriate mutation module.
- Add any new input or output types in
${project_dir}/environment/types.jsif the method needs them. - Implement the controller method in the matching controller module under
${project_dir}/environment/controllers/. - Call the controller from the GraphQL resolver.
For example, the existing realm.system.enter_session method is wired through:
${project_dir}/environment/interfaces/graphql/mutations/realms/system.jsfor the GraphQL field${project_dir}/environment/controllers/realms/system.jsfor the controller${project_dir}/environment/realms.jsfor the shared realm-session logic
Example Extension: Email Request and Code Verification
One good extension path is to turn the existing placeholder email flow into a fully implemented authentication path.
The GraphQL surface already has these mutation shapes:
mutation RequestEmailCode {
agent {
person {
request {
email(
agent_person: {
gauze__agent_person__email: "user@example.com"
}
) {
success
}
}
}
}
}mutation VerifyEmailCode {
agent {
person {
verify {
email(
code: {
code: "123456"
}
) {
success
}
}
}
}
}Right now, those resolver paths lead to placeholder controller methods in ${project_dir}/environment/controllers/agent_person.js. To make them real, you would usually:
- Implement
request_emailso it creates or delivers a verification code and stores the pending challenge in session data. - Implement
verify_emailso it checks the submitted code and records a success step in session data. - Add any new step dependencies in
project.default.steps. - Add the new success step to
authentication.proxy,authentication.realms.<realm>, orauthentication.agents.<agent_type>if it should gate later access.
This would make a good tutorial because it touches the full environment-realm stack:
- GraphQL mutation fields.
- Environment input and output types.
- Controller logic.
- Session data updates.
- Project authentication configuration.
If you want, the next step can be a dedicated tutorial page that walks through implementing person.request.email and person.verify.email end to end.
Expand Authentication Requirements
Adding a new mutation alone does not make it part of the authorization flow. If the new method should participate in sign-in or realm entry requirements, update the project authentication configuration as well.
The default structure lives in ${project_dir}/gauze.js:
stepsdefines dependency relationships between authentication steps.authentication.proxydefines which successful steps are required beforeenvironment.sign_incan create a proxy session.authentication.realms.<realm>defines which successful steps are required before entering a target realm session.authentication.agents.<agent_type>defines additional requirements for specific target agent types.
If you add a new step such as steps.account.verify.totp.success, you usually need to:
- Record that step in the session data from your new controller method.
- Add it to
stepsif it depends on earlier steps. - Add it to
authentication.proxy,authentication.realms.<realm>, orauthentication.agents.<agent_type>depending on where it should be enforced.
Expand Realm Offerings
If you want the environment realm to mint JWTs for an additional realm, follow the existing system, database, and kernel pattern:
- Add a signing function in
${project_dir}/environment/authentication.js. - Add a controller under
${project_dir}/environment/controllers/realms/. - Add a GraphQL mutation type under
${project_dir}/environment/interfaces/graphql/mutations/realms/. - Register it in
${project_dir}/environment/interfaces/graphql/mutations/realm.js. - Add the realm configuration to
${project_dir}/gauze.jsunderrealmsandauthentication.realms.
Related Pages
- Read Authentication and Authorization for the broader model.
- Read GraphQL Overview for endpoint and bearer-token behavior.