Web API History Series • Post 88 of 240
Chapter 88: Before OAuth—How 1995–1998 Web Patterns Shaped Delegated Authorization
A chronological, SEO-focused guide to OAuth 1.0 and delegated authorization in web API history and its role in the long evolution of web APIs.
Post 88 of 240 — Browser scripting, CGI, forms, and early dynamic web integration
OAuth 1.0 and Delegated Authorization in Web API History: What 1995–1998 Quietly Built
OAuth 1.0 is usually remembered as a late-2000s breakthrough: a practical way for one website or app to access a user’s data on another service without asking for the user’s password. But the problems OAuth 1.0 solved didn’t suddenly appear. They were baked into the web’s earliest “API-like” integrations—especially in the mid-to-late 1990s, when browsers were learning to run scripts, servers were learning to generate pages dynamically, and HTML forms became a universal data transport.
This chapter looks at the era roughly spanning 1995–1998, when web developers were already building integrations that smelled like modern web APIs, even if they weren’t calling them that. The story here isn’t “OAuth existed back then” (it didn’t). The story is that the web’s primitive integration patterns forced developers to invent ad-hoc delegation and authentication approaches—some clever, many risky—and those approaches eventually motivated standardized delegated authorization.
1995–1998: The Web’s “API Surface” Was Mostly HTML
In the mid-1990s, the web’s dominant integration mechanism wasn’t JSON or even XML. It was HTML itself. If you wanted one system to talk to another system, you commonly did it by:
- Submitting an HTML form to a server endpoint (often a CGI program), using GET or POST.
- Embedding URLs that triggered server-side actions (links that caused state changes were more common than we’d accept today).
- Scraping responses that were primarily meant for browsers, not programs.
Because browsers were the universal client, “integration” often meant “simulate what a browser does.” That meant dealing with cookies, redirects, query strings, and hidden form fields. In other words: the building blocks of delegated access were emerging as web conventions, not as a formal standard.
CGI and Forms: Early Dynamic Web Integration as Proto-APIs
Common Gateway Interface (CGI) scripts were among the first widespread ways to create dynamic, parameterized endpoints. From an integration perspective, CGI normalized an important idea: an endpoint can accept input parameters and return a computed response, generated on demand.
That’s very close to the mental model of a web API. The difference was that the response format was usually HTML, because the human-with-a-browser was the intended consumer. Still, the mechanics—HTTP requests carrying parameters—made it possible for other systems to call those endpoints too, either through server-side HTTP clients or by automating a browser session.
HTML forms deserve special credit as a “universal client library.” A form submission encoded data in a predictable way, and browsers handled the tedious parts. Developers didn’t need SDKs to “call” an endpoint; they needed a form and a submit button. That pattern made web-to-web integration accessible, but it also came with a security side effect: if you could submit a form, you could potentially trigger actions, which put pressure on authentication and session management.
For a snapshot of what the platform was standardizing around then, the HTML 4.0 specification (published in the late 1990s) captures the era’s assumptions about forms, scripting, and documents as the core web interface. See the spec here: https://www.w3.org/TR/REC-html40/.
Browser Scripting: A New Player in the Trust Story
As JavaScript spread through mainstream browsers, the client became programmable. That mattered for web APIs and authorization history because it blurred the line between:
- What the user explicitly did (clicking a link, submitting a form), and
- What the page caused to happen (auto-submitting forms, building URLs, firing requests).
Even if cross-origin restrictions limited direct reading of responses, a script could still initiate navigation or send requests in ways that influenced server state. The more we let pages act like applications, the more we needed servers to reliably answer: “Is the user really authorizing this action?” and “Is this request coming from a trusted party?”
This period also normalized patterns like session cookies and server-side sessions, which created continuity across requests. Continuity is a prerequisite for delegation: you can’t delegate access if there’s no stable identity or session context to tie permissions to.
The Delegation Problem Appears: “Please Give This Other Site Access”
Even in 1995–1998, users wanted websites to work together. The names of the services have changed over the decades, but the user intent is familiar:
- “Show my information from that other account here.”
- “Let this tool check something on my behalf.”
- “Let this site post or update something for me elsewhere.”
Without a standard for delegated authorization, developers fell back to a few options:
- Password sharing: a third-party tool asked the user for their credentials to Service A, stored them, then logged in as the user. This enabled delegation but destroyed the security boundary between user and third party.
- Shared secret per integration: two sites agreed on a password or token “out of band.” This worked for server-to-server integrations but did not scale to user-specific delegation.
- IP allowlists and network trust: trusting where a request came from rather than who it represented. Useful in controlled environments, fragile on the public internet.
- Manual export/import: users downloaded data from one site and uploaded it to another. Secure-ish but not automated and not “API-like” in the modern sense.
All of these approaches highlight the same missing primitive: a user-scoped permission that can be granted to a third party without handing over the user’s primary credential.
Why OAuth 1.0’s Core Ideas Make Sense Against This Background
OAuth 1.0 eventually standardized a delegated authorization flow with a few key properties:
- Users authenticate directly with the service that owns the data (the “provider”), not with the third-party app.
- The third-party app gets a limited token, not the user’s password.
- Requests are signed (in OAuth 1.0’s case) to protect tokens in transit and reduce replay risks—especially relevant when TLS wasn’t consistently applied everywhere in the early web’s cultural memory.
Those choices aren’t arbitrary. They map directly to failure modes that were already visible in 1990s integration practices:
- Password sharing was “delegation by impersonation.” OAuth replaced impersonation with scoped permission.
- Form-based logins were easy for humans and easy to automate, which meant credentials could be harvested and replayed. OAuth made the user’s password irrelevant to the third party.
- HTML-as-API forced developers into brittle scraping and session handling. OAuth, later paired with purpose-built API endpoints, shifted integrations toward explicit machine interfaces.
Seen from the 1995–1998 perspective, OAuth 1.0 looks like the eventual correction to a decade of improvising around sessions, cookies, and logins as the only universal interface.
Early Web Constraints That Quietly Shaped Delegated Authorization
To understand why delegated authorization took so long to standardize, it helps to remember what was constrained in this era:
1) Authentication was page-centric, not resource-centric
In the 1990s, authentication often meant “can you view this page?” not “can this app access this specific resource with this specific permission?” That page-centric mindset is natural when HTML is the primary output. OAuth’s token scopes (even though scoping evolved more in later standards) reflect a shift toward resource-centric permissions.
2) Sessions were the glue, and sessions weren’t portable
Cookies and session IDs were designed to keep a user logged into a single site. Delegation requires portability: a permission artifact that can be presented by a different client. OAuth tokens are, effectively, a portable session-like artifact with explicit delegation semantics.
3) Integrations were common, but standardization wasn’t
Vendors built partnerships and custom integrations, but each one used different parameters, different signing tricks, and different ideas of identity. OAuth 1.0’s historical importance is that it turned “custom partnership auth” into something closer to a repeatable pattern.
What “Delegated Authorization” Meant Before We Had the Term
In modern language, delegated authorization means: a user gives App B permission to access Service A, typically with a limited scope and revocability, without giving App B the user’s primary credentials for Service A.
In 1995–1998, developers approximated that with user experience patterns like:
- “Enter your username/password for the other site here” (credential delegation rather than authorization delegation).
- “Click here to confirm” pages that were really just normal logins plus a redirect back—an early hint of the later idea that the provider should be the place where the user consents.
- Hidden fields and return URLs to preserve workflow across sites, foreshadowing the redirect-based flows that would later become central to OAuth-style designs.
If you build automation today, you still encounter echoes of these patterns when you’re forced to integrate with systems that have no real API. For modern perspectives on automation and integration pitfalls, you can also explore resources at https://automatedhacks.com/.
Takeaway: OAuth 1.0 Was a Standardized Answer to a 1990s Question
The mid-to-late 1990s built the web’s first practical integration toolbox: forms for input, CGI for dynamic endpoints, cookies for continuity, and browser scripting for richer interaction. That toolbox made it possible for websites to cooperate—but it didn’t provide a safe, user-friendly way to delegate access.
OAuth 1.0 is best understood as the eventual “grown-up” mechanism for a problem that early web developers could already see: if every integration requires passwords, the web can scale in features, but it can’t scale in trust.
FAQ
Did OAuth exist in 1995–1998?
No. OAuth 1.0 came significantly later. This period matters because it established the integration patterns (forms, cookies, scripted flows, redirects) and the security failures (password sharing, brittle scraping) that OAuth-style delegated authorization was designed to fix.
What counted as a “web API” in the mid-1990s?
Often it was an HTTP endpoint implemented as a CGI script that accepted parameters and returned a dynamic response—usually HTML. Even when not labeled an API, it functioned as a programmable interface for another system willing to send HTTP requests.
Why is delegated authorization different from authentication?
Authentication answers “Who are you?” Delegated authorization answers “What is this third party allowed to do on your behalf?” The 1990s web was good at the first question via logins and sessions, and much weaker at the second without sharing credentials.
How did users typically “delegate” access before OAuth?
Most commonly by giving their username and password to the third-party tool or site, which then logged in and acted as them. It worked, but it was risky and hard to control or revoke in a granular way.
