From Prompts to Specifications: Building a Secure API with an AI-Native SDLC

How Spec-Driven Development changes the way we design, build, test and release software using AI.

1. AI can write an API. But can it build a secure one?

Building a backend API with an AI coding assistant is relatively straightforward.

You can ask an assistant to create a Python FastAPI application with PostgreSQL, JWT authentication and endpoints for uploading and retrieving documents. Within minutes, it may generate the project structure, database models, API routes and basic tests.

The application might even run successfully on the first attempt.

But that tells us relatively little about whether the software is ready for production.

Does the API validate the JWT signature, issuer and audience correctly? Can one authenticated user access another user's documents? Are uploaded files inspected before they become available for download? What happens when a request fails halfway through a database transaction?

These are not simply coding questions. They concern requirements, architecture, security and software verification.

A prompt such as "build me a secure document management API" leaves most of these decisions to the AI model.

The resulting code may be functional while still containing serious security weaknesses.

This is where Spec-Driven Development (SDD) becomes relevant.

Instead of treating the prompt as the primary instruction for generating software, SDD establishes explicit specifications that guide implementation and provide a basis for verification.

The objective is not to eliminate developers. It is to make AI-generated software more predictable, reviewable and testable.

2. What changes with Spec-Driven Development?

Traditional software development generally follows a sequence of requirements gathering, architecture design, implementation, testing and deployment.

AI coding assistants have accelerated parts of this process, particularly code generation, refactoring and test creation.

However, faster code generation does not necessarily improve the quality of requirements or the effectiveness of verification.

Spec-Driven Development attempts to address that problem by making specifications central to the engineering workflow.

A specification describes what the system must do, the constraints it must satisfy and the conditions under which its implementation can be accepted.

The AI then works from that specification rather than relying on a collection of conversational prompts.

Engineering activityPrompt-driven developmentSpec-driven development
RequirementsDescribed in promptsMaintained as structured, version-controlled specifications
ArchitectureOften inferred by the AIExplicit technical constraints and design decisions
ImplementationGenerated from conversational instructionsGenerated against defined requirements and tasks
TestingOften requested after implementationAcceptance criteria defined before implementation
SecurityDepends on prompt completenessSecurity requirements and verification gates are explicit
Change managementPrompts and code changes may divergeSpecifications, implementation and tests can be reviewed together
Human oversightPrimarily code reviewSpecification, architecture, security and code review

SDD is not a new replacement for requirements engineering, test-driven development or DevSecOps.

Its value lies in bringing these established practices into AI-assisted software delivery.

An important qualification is that specifications are not automatically correct. Poor requirements can still produce poor software, even when an AI follows them precisely.

Comparing prompt-driven code generation with a specification-driven engineering workflow.

3. Our example: A secure document management API

To make the discussion practical, consider a backend service that allows authenticated users to upload, retrieve and delete business documents.

The application will use a relatively conventional technology stack:

LayerTechnology
API frameworkPython and FastAPI
DatabasePostgreSQL with SQLAlchemy
AuthenticationOpenID Connect-compatible identity provider
AuthorizationOAuth scopes and object-level access checks
Document storagePrivate S3-compatible object storage
Database migrationsAlembic
Automated testingpytest and HTTPX
Security analysisSemgrep, Bandit and pip-audit
Delivery pipelineGitHub Actions or GitLab CI

The service exposes four endpoints:

  • POST /api/v1/documents — upload a document.
  • GET /api/v1/documents — list documents accessible to the user.
  • GET /api/v1/documents/{id} — retrieve document metadata.
  • DELETE /api/v1/documents/{id} — delete an authorized document.

A separate authenticated download endpoint could be introduced to stream file contents without exposing permanent public storage URLs.

The API must also enforce several security requirements.

Users must authenticate with valid access tokens. They must not be able to retrieve documents belonging to other users. Uploaded files must be validated and scanned before becoming available. Storage buckets must remain private, and sensitive information must not appear in application logs.

These requirements are straightforward to describe in English.

The challenge is translating them into an implementation that can be tested and verified consistently.

4. Step one: Define the specification before generating code

In a prompt-driven workflow, a developer might begin with:

Build a secure document management API using FastAPI, PostgreSQL and S3. Include JWT authentication and tests.

The AI must interpret what "secure" means.

It may implement token authentication without object-level authorization. It might validate file extensions but not file contents. It could return permanent object storage URLs or expose internal exception details.

A specification-driven workflow begins differently.

We first define the application's functional behavior, security constraints and acceptance criteria.

Example: Document upload specification

feature: secure-document-upload
version: 1.0

endpoint:
  method: POST
  path: /api/v1/documents

authentication:
  mechanism: OAuth2 Bearer Token
  validation:
    - signature
    - issuer
    - audience
    - expiration
    - allowed_algorithm

authorization:
  required_scope: documents:write
  owner: authenticated_subject

upload:
  allowed_media_types:
    - application/pdf
  max_file_size_mb: 10
  content_validation: required
  malware_scanning: required
  quarantine_before_scan: true

storage:
  visibility: private
  encryption_at_rest: required
  object_key: server_generated

acceptance_criteria:
  - valid_upload_returns_201
  - invalid_token_returns_401
  - insufficient_scope_returns_403
  - oversized_upload_returns_413
  - malicious_file_is_not_downloadable
  - cross_user_access_is_denied

This example is illustrative rather than a complete executable specification.

Some requirements still need additional definition. For example, the team must decide how malware-scanning failures are handled, how long quarantined files are retained and whether asynchronous uploads return a pending status before the document becomes available.

Those decisions should be resolved before implementation.

The specification also needs to describe the data model, API response schemas, error handling, transaction boundaries and operational requirements.

The important change is that these decisions are documented and reviewed rather than left entirely to the AI coding assistant.

5. Step two: Generate an implementation plan

Once the specification is approved, an AI agent can help translate it into a technical implementation plan.

The plan should define the application's components, dependencies and engineering tasks.

For our document management API, the architecture could look like this:

Reference architecture for a secure document management API using FastAPI, PostgreSQL and private object storage.

Client application

Authenticated requests are sent over HTTPS.

↓

API gateway or reverse proxy

Enforces request limits, TLS configuration and applicable network controls.

↓

FastAPI application

Validates access tokens, enforces authorization, validates requests and coordinates document operations.

↓

PostgreSQL and private object storage

PostgreSQL maintains document metadata and ownership records. Object storage holds uploaded files.

↓

Asynchronous malware-scanning worker

Inspects quarantined documents and updates their status before they become downloadable.

This architecture separates API request processing from potentially slow file-scanning operations.

It also introduces an important design decision: uploading a file and making that file available are different operations.

A document might move through the following states:

PENDING → SCANNING → AVAILABLE

If scanning fails, the document moves to REJECTED or a controlled failure state.

This prevents the application from treating an unverified upload as a trusted document.

The AI can propose this design, but the engineering team should review the storage permissions, transaction behavior, failure recovery and threat model before implementation begins.

6. Step three: Turn specifications into engineering tasks

A useful SDD workflow breaks the implementation plan into smaller, verifiable tasks.

For example:

TaskDeliverableVerification
Implement JWT validationAuthentication dependencyInvalid and expired token tests
Implement authorizationScope and ownership checksCross-user access tests
Create database schemaDocument metadata modelMigration and constraint tests
Implement upload handlingValidated file uploadFile type and size tests
Integrate private storageStorage serviceUnauthorized access tests
Add malware scanningQuarantine and scan workflowMalicious and failed-scan tests
Implement document retrievalMetadata and download handlingOwnership and state tests
Configure CI pipelineAutomated quality gatesPipeline execution evidence

These tasks can be assigned to an AI coding agent sequentially or through a controlled orchestration workflow.

However, parallel agents are not automatically better.

Authentication, authorization, storage and database operations have shared dependencies. Generating them independently without coordination can produce incompatible interfaces or duplicated logic.

For a small API, a single coding agent working through approved tasks may be more reliable than a collection of autonomous agents.

7. Step four: Implement using AI, but verify independently

The AI coding agent can now generate the FastAPI routes, database models, authentication dependencies, storage integration and tests.

For example, the authorization logic should ensure that a document is accessible only when the authenticated user has the required permission and the document belongs to that user or is otherwise explicitly shared with them.

The important point is that a valid JWT does not automatically authorize access to every resource.

Authentication establishes the identity of the requester.

Authorization determines what that requester is permitted to do.

This distinction is particularly important for APIs that expose resource identifiers.

An attacker might authenticate successfully and then change a document identifier in the URL to attempt to retrieve another user's data.

This is an example of broken object-level authorization, a risk identified in the OWASP API Security Top 10.

A specification-driven implementation should require explicit ownership checks and tests that verify unauthorized access is rejected.

The coding agent should not be allowed to declare the task complete simply because the endpoint returns a successful response for an authorized user.

Negative tests are equally important.

8. Step five: Security becomes an acceptance condition

Security testing should be defined before the AI generates the implementation.

For our API, we can establish the following acceptance tests.

Test scenarioExpected behavior
Valid JWT and authorized uploadRequest accepted
Invalid JWT signatureHTTP 401
Expired access tokenHTTP 401
Missing required scopeHTTP 403
Access to another user's documentHTTP 404, under the chosen non-disclosure policy
Upload exceeds configured sizeHTTP 413
Unsupported file formatHTTP 415
Malicious file uploadedFile remains unavailable
Direct anonymous access to storageAccess denied
SQL injection attemptNo unauthorized database operation
Application secret committedSecret detection blocks the change

These tests provide evidence that the implementation satisfies selected requirements.

They do not prove that the application is completely secure.

Automated scanners cannot identify every business logic vulnerability. Test coverage can also be high while important security scenarios remain untested.

For this reason, the pipeline should combine automated testing with code review, threat modelling and appropriate security assessment.

A useful CI/CD sequence would be:

  1. Validate specification consistency.
  2. Run formatting, linting and type checks.
  3. Execute unit and integration tests.
  4. Run static application security testing.
  5. Scan dependencies and repository secrets.
  6. Execute authorization and API security tests.
  7. Build and scan the deployment artifact.
  8. Require approval before production deployment.

The AI can assist with generating tests and explaining failures, but it should not have unrestricted authority to modify acceptance criteria or disable security gates merely to make a pipeline pass.

9. Step six: Where GitHub Spec Kit fits

One implementation approach is to use GitHub Spec Kit, an open-source toolkit designed to support specification-driven development with AI coding agents.

Its workflow helps structure the development process around specifications, implementation planning and task generation.

For our API, the repository could contain:

secure-document-api/
├── .specify/
│   └── memory/
│       └── constitution.md
├── specs/
│   └── 001-document-management/
│       ├── spec.md
│       ├── plan.md
│       ├── tasks.md
│       ├── data-model.md
│       └── contracts/
├── src/
│   ├── api/
│   ├── auth/
│   ├── models/
│   ├── services/
│   └── workers/
├── tests/
│   ├── unit/
│   ├── integration/
│   └── security/
└── .github/
    └── workflows/

The repository constitution can establish project-wide engineering rules, including mandatory authorization checks, test requirements, coding standards and restrictions on handling secrets.

Feature specifications define the required behavior. Implementation plans describe technical decisions, while task files guide the coding agent through the work.

The precise files and generated structure depend on the Spec Kit version and project configuration.

Spec Kit does not itself replace an identity provider, security scanner, CI/CD system or human code review.

It provides structure for the development workflow. The surrounding engineering environment remains responsible for enforcement.

An AI-native SDLC incorporating specifications, AI-assisted implementation, independent verification and controlled deployment

10. Can the same approach work with a locally hosted SLM?

One reason to separate specifications from model selection is that the same engineering workflow can potentially support different AI development environments.

An organization might use a cloud-hosted coding model, a locally deployed small language model or a hybrid arrangement.

For a local setup, the architecture could consist of:

  • GitHub Spec Kit for specification management.
  • A local coding model served through an inference runtime.
  • An agent interface capable of reading and modifying repository files.
  • Git for version control.
  • Containerized PostgreSQL and object storage for integration testing.
  • A local or self-hosted CI runner for independent verification.

The model would receive the relevant specifications, architecture constraints and implementation tasks.

It could then generate or modify code within a controlled development environment.

The main limitation is not whether an SLM can produce Python syntax.

It is whether the model can consistently understand requirements, maintain context across multiple files, respect architectural constraints and recover from implementation errors.

A smaller model may perform well on narrowly defined tasks but struggle with changes involving authentication, asynchronous processing, database transactions and distributed storage.

This is where SDD may offer a practical advantage.

By breaking a large engineering problem into smaller tasks with explicit acceptance criteria, we reduce the amount of interpretation required from the model.

That does not guarantee better results. It creates a hypothesis that can be tested.

11. Azure, AWS and Google Cloud: Does the methodology change?

The underlying development methodology does not need to change significantly between cloud platforms.

The specifications, security requirements and acceptance criteria can remain consistent.

What changes is the development tooling, model hosting, identity integration and deployment infrastructure.

AreaMicrosoft AzureAWSGoogle Cloud
AI development toolingGitHub Copilot and compatible agentsKiro or compatible coding agentsGemini-based coding agents
Model infrastructureAzure AI servicesAmazon BedrockVertex AI
Application hostingAzure Container Apps / AKSECS / EKSCloud Run / GKE
DatabaseAzure Database for PostgreSQLAmazon RDS for PostgreSQLCloud SQL for PostgreSQL
Object storageAzure Blob StorageAmazon S3Cloud Storage
CI/CDAzure Pipelines / GitHub ActionsCodePipeline / GitHub ActionsCloud Build
Identity and accessMicrosoft Entra ID and Azure RBACIAM and an appropriate OIDC providerCloud IAM and an appropriate OIDC provider

These are possible implementation choices, not a requirement to use every service listed.

Cloud IAM and RBAC control access to infrastructure resources; they do not automatically implement application-level document ownership.

Likewise, using a managed AI model does not automatically make the generated code secure.

The same security specifications and verification requirements should apply regardless of the chosen cloud provider.

For enterprises already committed to a particular cloud environment, this separation is useful. They can introduce SDD without replacing their entire application delivery stack.

12. How should we measure the results?

To determine whether SDD improves software engineering outcomes, we need more than a demonstration showing that the API works.

A controlled comparison would be more informative.

We could implement the same API using four approaches:

ApproachMethod
Traditional developmentHuman developers using conventional tooling
Prompt-driven AIAI coding assistant with a general implementation prompt
Spec-driven AIStructured specifications with a cloud coding model
Spec-driven local SLMIdentical specifications using a locally hosted model

Each implementation would be evaluated against the same independently maintained test suite.

Useful measurements include:

Engineering effort: Human time spent specifying, implementing, debugging and reviewing the application.

Functional correctness: Percentage of acceptance tests passed without modifying the test criteria.

Security: Number and severity of vulnerabilities identified through independent testing.

Rework: Number of iterations required before the implementation meets the acceptance criteria.

Maintainability: Code complexity, duplication, architectural consistency and review findings.

Cost: Model inference expenditure, compute usage, tooling and human engineering effort.

The comparison must account for the time spent creating and reviewing specifications.

Otherwise, SDD may appear faster simply because part of the engineering effort has been excluded from the measurement.

It would also be important to distinguish between defects discovered during development and defects remaining in the final implementation.

A single successful run would not establish that one methodology is consistently superior. Repeated trials, comparable developer experience and identical evaluation criteria would produce more credible evidence.

Until such an experiment is conducted, claims about productivity improvements or security gains should be treated as hypotheses rather than demonstrated results.

13. What SDD does not solve

Spec-Driven Development introduces discipline into AI-assisted engineering, but it has limitations.

Specifications can be incomplete or wrong. An AI can faithfully implement a requirement that contains a security flaw or fails to reflect the actual business need.

Tests can reproduce the same misunderstanding. If an AI generates both implementation and tests from an incorrect specification, both may agree while the software remains defective.

Architecture still requires engineering judgment. Decisions involving distributed transactions, authorization boundaries, failure recovery and operational resilience cannot be reduced to code generation alone.

AI agents introduce additional security risks. Agents with repository, terminal or deployment access require restrictions on tool permissions, secrets and execution environments. Repository content and external documentation should also be treated as potentially untrusted input.

Specifications require maintenance. When requirements change, the specification, implementation and tests must remain aligned. Version control alone does not ensure that alignment.

These limitations matter because SDD should not be presented as a way to automate away software engineering responsibilities.

Its purpose is to make those responsibilities more explicit and easier to verify.

14. From AI-assisted coding to an AI-native SDLC

The broader implication of Spec-Driven Development is that AI can participate in more stages of the software development lifecycle than code generation alone.

AI can help clarify requirements, identify inconsistencies, propose architectures, break work into tasks, implement features, generate tests and investigate failures.

But these activities need a common engineering reference.

Specifications provide that reference.

In an AI-native SDLC, the developer's responsibilities increasingly include defining requirements precisely, establishing architectural constraints, reviewing AI-generated decisions and verifying that implementations satisfy the intended behavior.

This does not mean every organization needs autonomous development agents or a completely new delivery platform.

An existing development team can begin with one service, one repository and a small number of well-defined specifications.

The secure document API provides a useful starting point because it exposes several problems that simple AI coding demonstrations often overlook: authentication, authorization, file validation, asynchronous processing, data protection and security testing.

The practical test is whether the resulting software satisfies independently verified requirements, not how quickly an AI generates the first version of the code.

References