Inspiration

AI agents are becoming capable of doing much more than answering questions. They can interact with websites, update accounts, send messages, schedule appointments, change records, and perform other real actions for people.

That created a question I kept coming back to:

Why should an AI need my credentials just because I want it to perform one specific action?

If I ask an agent to change a delivery address, I may want it to have permission to perform exactly that change. I do not necessarily want to give it my password, a reusable API key, an OAuth token, a broad authenticated browser session, or some other credential that authorizes much more than the task I requested.

GWEN started from the idea that human authentication and agent authority should be separate things.

The human should authenticate as the human.

The AI should receive only the smallest amount of authority necessary for the action the human actually approved.

That became the central model behind GWEN:

Humans authenticate. Agents receive temporary authority.

And the principle behind the project:

Give AI authority. Never give it your credentials.

WebMCP was a natural fit for this idea because it allows a website to expose structured capabilities directly to an AI agent while the application still controls exactly what those capabilities mean and when they may be used.

Instead of treating an AI as another fully logged-in user, GWEN treats the AI as an agent requesting narrowly scoped authority from a human-controlled security boundary.

The delivery-address change in the demo is intentionally simple.

The important part is not the address.

The important part is the authority model behind it.

What it does

GWEN is a working WebMCP security prototype that separates human authentication from agent authority.

A visitor begins by using their own email address to verify control of a browser session through a temporary, one-time sign-in link.

The AI never receives that sign-in link, the browser session cookie, the Gmail App Password, or the visitor's credentials.

Authentication establishes that there is a verified email-controlled human session.

It does not automatically authorize an AI agent to make changes.

Once the browser is verified, GWEN exposes structured WebMCP capabilities.

The first capability is get_gwen_capabilities.

This allows an agent to discover what GWEN supports and understand the authority model without receiving human credentials.

The second capability is request_address_change_authority.

This allows an agent to request permission for one exact delivery-address change and provide a reason for the request.

Nothing changes when the request is made.

Instead, GWEN displays the exact proposed value to the human in a visible authorization panel.

The human can explicitly choose Authorize GWEN or Deny.

Only after the human approves the exact request does GWEN dynamically expose another WebMCP capability:

commit_approved_address_change

This temporary commit capability does not accept another address.

The value approved by the human has already been bound on the server.

For example, if the human approves:

42 WebMCP Street

the AI cannot substitute:

99 Something Else Street

during final execution.

There is no replacement-address parameter in the final commit tool.

The agent receives authority to execute the exact action the human approved.

The resulting GWEN Grant is:

  • bound to the verified human session
  • bound to one specific action
  • bound to the exact approved value
  • short-lived
  • limited to one authorized use
  • consumed after successful execution

The current WebMCP grant has a maximum lifetime of 120 seconds.

After successful execution, GWEN shows:

1 of 1 consumed

and:

Authority remaining: NONE

The temporary authority disappears.

GWEN then creates a persistent, human-bound audit receipt containing the action, previous value, approved new value, grant information, number of uses, remaining authority state, timestamp, and an internal identity hash associated with the verified session.

The design principle is:

Temporary authority should disappear. Evidence of what happened should remain.

GWEN also includes Qwen, a local AI email conversation assistant running through Ollama.

Qwen's conversation authority is deliberately separate from WebMCP action authority.

A verified visitor can have a normal email conversation with Qwen without giving Qwen the human's Gmail password, magic-link token, or GWEN browser-session credential.

The Qwen email capability has a hard 10-minute lifetime.

Replies do not extend the original deadline.

Per-message capabilities are single-use. Attachments are blocked. Oversized messages are rejected. URLs are not automatically fetched. Automated reply loops are guarded against, and restarting the Qwen worker revokes outstanding Qwen email capabilities.

The visible email address remains normal.

The short-lived capability is carried through email reply-chain metadata instead of forcing the user to communicate through a strange tokenized email address.

GWEN can also maintain compact encrypted continuity for returning verified users without keeping their old authorization alive.

That created another important design rule:

Memory is not authority.

How we built it

GWEN's primary security and authority implementation is written in Rust using Axum.

I built GWEN as a solo developer and deliberately kept the architecture small enough that I could trace the complete authority path myself.

A simple rule emerged while I was building it:

Browser shows state. Rust decides state. Redis authorizes state. SQLite records state.

Rust and Axum

Rust is the main policy and application layer.

It handles:

  • email-based browser verification
  • temporary browser sessions
  • server-side authorization
  • WebMCP grant creation
  • human approval
  • exact-value binding
  • one-use execution
  • persistent audit receipt creation
  • Qwen worker supervision
  • application lifecycle and policy enforcement

The security-critical authorization decisions are made on the server.

Browser JavaScript presents the state and exposes WebMCP tools, but it is not trusted to decide whether an action is actually authorized.

WebMCP

GWEN registers structured WebMCP tools through the browser's model-context interface using document.modelContext.registerTool().

The initial capabilities are available for agent discovery.

The final commit capability only appears after the human has approved the exact requested action.

This means the available WebMCP tool surface itself reflects the current authorization state.

Before approval, the agent has no commit authority.

After approval, the temporary commit capability appears.

After successful execution, the capability disappears.

The final commit tool intentionally accepts no replacement address because the human-approved value is already bound on the server.

Redis

GWEN uses a dedicated Redis instance at:

127.0.0.1:6387

Redis stores temporary state including:

  • one-time login capabilities
  • browser sessions
  • WebMCP grants
  • remaining authorized uses
  • temporary Qwen email capabilities
  • worker ownership and lease state

The host also has other software using Redis on port 6379.

GWEN deliberately does not use or modify that Redis instance.

Redis is a good fit for GWEN because authorization should be temporary, expiring, and capable of being consumed atomically.

SQLite

SQLite stores information that should persist after temporary authority disappears.

That includes:

  • WebMCP audit receipts
  • Qwen client accounting
  • returning-user metadata
  • encrypted compact Qwen continuity

This creates a deliberate separation:

Temporary authority belongs in Redis.

Persistent records belong in SQLite.

Human verification

GWEN uses temporary one-time email verification.

The sign-in link is short-lived and single-use.

The resulting browser session also has a hard 10-minute lifetime.

GWEN verifies control of the email-based session used by the demonstration.

It does not claim to prove a person's legal identity.

The correct description is therefore email-controlled session verified, rather than claiming biometric, legal, government, or cryptographic proof of personal identity.

Qwen and Ollama

Qwen runs locally through Ollama using qwen3-coder:30b.

Qwen is the conversation assistant.

Qwen is not the source of WebMCP authorization.

The Qwen worker receives trusted GWEN project grounding separately from untrusted incoming email content.

That means an incoming email cannot redefine GWEN's trusted security architecture simply by containing instructions that claim to change the system's rules.

Qwen can also use encrypted compact continuity for returning verified users.

Gmail

Gmail provides transport for:

  • one-time GWEN verification links
  • Qwen email conversations

The AI does not receive the human user's Gmail credentials.

The short-lived Qwen capability is associated with the email conversation through reply-chain metadata while the visible sender remains a normal email account.

Cloudflare Tunnel

The live demonstration is available at:

https://gwen.icreateomnom.com

The application itself remains bound locally at:

127.0.0.1:8787

Cloudflare Tunnel exposes the live demonstration without requiring me to open a public inbound application port.

For the final challenge deployment I moved GWEN from my development system to a dedicated machine running the live application, local Qwen model, dedicated Redis state, SQLite database, and Cloudflare connection.

Frontend

The browser interface is intentionally built with vanilla HTML, CSS, and JavaScript rather than a large frontend framework.

It visibly shows:

  • WebMCP connection state
  • verified-human state
  • whether credentials were shared with the AI
  • current demo-account state
  • agent authorization requests
  • the exact requested value
  • human approval and denial controls
  • remaining authority
  • persistent audit receipts
  • a small developer event stream

I wanted the authorization lifecycle to be visible to the human instead of hiding consequential decisions behind an invisible AI workflow.

Challenges we ran into

Even though I built GWEN as a solo developer, I kept this Devpost heading as provided by the submission form.

One of the most useful things about building GWEN was discovering that an authorization architecture can be conceptually correct and still fail because of very small implementation details.

Making one-use authority truly one-use

Hiding a button after execution is not security.

The server itself has to make repeated execution impossible.

GWEN therefore validates and consumes grants server-side.

A grant must:

  • exist
  • belong to the current verified session
  • have approved status
  • still contain the exact server-bound proposed value
  • have exactly one authorized use remaining

The profile change and grant consumption are handled atomically in Redis.

After execution, another HTTP request cannot simply reuse the same grant.

Preventing post-approval value substitution

I wanted to make sure an agent could not show one value to the human for approval and then supply another value during final execution.

The solution was to separate the request capability from the commit capability.

The requested address is stored before approval.

After approval, the final commit tool accepts no replacement address.

The value the human saw is the value the server executes.

That became one of the most important parts of GWEN's design.

SQLite writer contention

During final testing I found a real concurrency bug.

The Python Qwen worker used SQLite INSERT OR IGNORE while recording already-seen login sessions.

On the ignored path, a transaction could remain open because that branch did not always complete the transaction.

The Qwen worker could therefore retain the SQLite writer lock.

At the same time, a WebMCP action could successfully validate and consume its authority in Redis.

Rust would then attempt to create the persistent audit receipt in SQLite.

The receipt insertion would wait on the SQLite writer lock and eventually fail.

From the browser, this initially looked like a broken Execute button.

The first execution could return a server error, while repeated clicks returned conflicts because the one-use Redis grant had already been consumed.

I traced the failure through the browser, Rust logs, Redis state, process ownership, and finally the Qwen SQLite code.

The fix was to guarantee that the SQLite transaction completes on every path, including when INSERT OR IGNORE finds an existing row.

After that correction, WebMCP execution and receipt creation worked correctly.

That debugging session reinforced an important lesson:

Database transaction boundaries are part of an authorization system too.

Making Qwen email capability natural

An earlier approach placed capability information into a modified visible email address.

It worked technically, but the interaction looked artificial.

I redesigned it so the visitor sees a normal Qwen email identity while GWEN carries the short-lived capability through the reply-chain metadata.

That kept the authorization mechanism while restoring a normal email experience.

New users versus returning users

A new browser session does not necessarily mean a completely new human.

At the same time, a returning user must not automatically inherit old authority.

I therefore separated:

  • browser-session lifetime
  • verified email identity
  • Qwen conversational continuity
  • current Qwen reply authority
  • WebMCP action authority

That allowed a genuinely new user to receive a first-time introduction while returning verified users could continue naturally without keeping an old authorization grant alive.

Worker lifecycle and revocation

During development, stale Qwen worker processes could survive restarts and retain worker ownership locks.

I tightened the worker lifecycle so ownership is explicit, the worker lock has a controlled lease, and restarting the Qwen worker revokes outstanding Qwen mail capabilities.

Moving the live deployment

For the final version I migrated GWEN away from the development workstation and onto a dedicated host.

I cloned the public source from GitHub, created fresh private deployment state, configured the dedicated Redis instance, initialized the SQLite database, verified the local Qwen model, authenticated the Cloudflare installation, created the new GWEN tunnel, and moved the live hostname to the new deployment.

The live site now operates independently of the machine where most of the development was performed.

Accomplishments that we're proud of

I built GWEN as a solo developer, so these are the accomplishments I am personally most proud of.

The biggest accomplishment is that GWEN became a complete working system instead of remaining an authorization diagram or concept.

The final prototype demonstrates:

  • real WebMCP tool registration
  • agent capability discovery
  • AI-requested authority
  • explicit human approval
  • server-bound exact values
  • dynamic temporary commit capabilities
  • single-use execution
  • server-side grant consumption
  • automatic authority removal
  • persistent human-bound audit receipts
  • one-time email browser verification
  • hard browser-session expiry
  • credential separation between the human and AI
  • isolated temporary authority state in Redis
  • persistent records in SQLite
  • a local Qwen conversational assistant
  • constrained Qwen email authority
  • hard Qwen conversation expiry
  • single-use Qwen message capabilities
  • restart-based capability revocation
  • encrypted returning-user continuity
  • normal visible email addressing
  • trusted grounding separated from untrusted email content
  • a live Cloudflare deployment
  • a public MIT-licensed GitHub repository
  • a Rust-centered security and authority architecture

I am particularly proud of the final WebMCP commit capability.

It accepts no replacement address.

The approved value is already bound on the server.

That small interface decision expresses the central idea behind GWEN:

The agent receives authority to perform what the human approved, not authority to decide afterward what the human meant.

I am also proud that the interface makes the disappearance of authority visible.

After an action executes, the user sees:

1 of 1 consumed

and:

Authority remaining: NONE

GWEN does not simply ask the human to trust that the permission is gone.

It shows the lifecycle of that authority as part of the product.

What we learned

As a solo developer, the biggest lesson I learned from building GWEN is that authentication and authorization should not be treated as the same thing when AI agents are involved.

A human being logged into a website should not automatically mean an AI agent inherits everything that human can do.

Likewise, an AI remembering a returning user does not mean that AI should retain authority over the user's account.

Thinking in terms of narrow capabilities gave me a much clearer model.

Instead of asking:

Is the AI logged in?

GWEN asks:

What exact action is being requested?

Which human-controlled session approved it?

What exact value did the human see?

Is that exact value the one that will execute?

How many times may this capability be used?

When should the authority disappear?

What evidence should remain after it disappears?

Those questions create a much smaller and more understandable security boundary.

I also learned that memory and authority should be treated as separate concepts.

A system can remember enough context to provide a useful returning-user experience without retaining an old ability to act.

That became:

Memory is not authority.

WebMCP also reinforced the importance of letting the website define the capability boundary.

The agent can discover and invoke structured tools, but the application still decides what those tools mean and what conditions must be satisfied before they succeed.

Finally, GWEN reminded me that authorization systems depend on ordinary engineering details.

A forgotten SQLite transaction, a stale worker, an incorrect timeout, a cached JavaScript file, a process-lifecycle mistake, or an improperly scoped capability can matter just as much as the high-level security model.

Building the complete system made those relationships much more concrete than they would have been in a design document alone.

What's next for GWEN Zero-Credential Agent Authority

The delivery-address change is intentionally a small demonstration.

The authority pattern is much more general.

I would like to apply the same model to additional consequential actions such as:

  • changing account settings
  • sending one specifically approved message
  • scheduling an appointment
  • approving a support operation
  • updating a business record
  • authorizing a file operation
  • interacting with another service
  • approving a bounded transaction
  • giving an AI one-time permission to access a sensitive workflow

The important pattern would remain the same:

Authenticate the human. Bind the exact action. Show the request to the human. Require explicit approval. Create the smallest possible capability. Execute only what was authorized. Consume the authority. Remove it. Keep a record of what happened.

A future version could also support richer capability restrictions.

For example, a capability could permit:

  • only one specific recipient
  • only a maximum transaction amount
  • only one particular file
  • only one API operation
  • only a defined time window
  • only one business record
  • only a specific sequence of actions

The long-term idea is not to create another identity system for AI.

It is to create a cleaner boundary between:

who the human is

what the human approved

and

what the agent is actually allowed to do

GWEN is my experiment in making that boundary understandable enough for humans to see and strict enough for software to enforce.

The live demonstration is available at:

https://gwen.icreateomnom.com

The public MIT-licensed source code is available at:

https://github.com/DonMerrow/gwen-webmcp

Give AI authority. Never give it your credentials.

Built With

Share this project:

Updates

Submission history