Dartvel, home
Docs
Features
Studio
Cloud
Compared

Search the site

GitHub
pub.dev

GETTING STARTED

Getting started
Existing Flutter apps
Existing Native apps
Run on your phone

APP

UI and styling
Routing
State
Accessibility
Keyboard shortcuts
Localization
Devices and desktop
Native device access
Media, 3D and XR

DATA

Data models
Forms
Search
Sync and offline
Import and export
Change capture
Database
Cache
File storage
Images
Privacy and erasure

BACKEND

Backend functions
Auth and sessions
Authorization
Queues and jobs
Workers and memory
Notifications and mail
Outbound HTTP
AI
Webhooks
GraphQL and OpenAPI
API keys and OAuth
Multi-tenancy
Billing and commerce
Modules

OPERATIONS

Edge security
Secrets and environments
Monitoring
Releases

SHIPPING

Build targets
Telegram Mini Apps
Static web hosting
Servers and deploying

REFERENCE

Testing
CLI reference
Coding agents

OPERATIONS

Edge security

Password guessing is slowed down on the sign-in your server already has, with no setup.

Add firewall rules, breached-password checks and GraphQL budgets where you need them.

ON THIS PAGE

Sign-in is rate limited by default

Refuse breached passwords

Block paths by country

Put a budget on GraphQL queries

Trust your proxy for the client address

Status

Sign-in is rate limited by default

With a database, the generated server guards sign-in and sign-up: 5 failures per account and 100 per source in 15 minutes.

A refused sign-in takes at least 400 ms and says the same thing whether or not the account exists.

Too many failures answer with DV-EDGE-005 and a retry time.

Refuse breached passwords

DVCredentialGuard credentialGuard() => DVCredentialGuard(
      provider: LocalAuthProvider(),
      velocity: DVVelocityLimiter(
        perAccount: const DVVelocityBudget(5, Duration(minutes: 15)),
      ),
      // A range query sends 5 characters of the password's SHA-1, never the password.
      breachedPasswords: DVRangeQueryBreachedPasswords.overHttp(
        (String prefix) => Uri.parse('https://api.pwnedpasswords.com/range/$prefix'),
      ),
    );

Copy code to clipboard

Sign-up and a password change are refused with DV-EDGE-004 when the password is in the breach list.

The range query goes through DV.Http, so its host must be declared under dartvel.http.hosts.

If the service is down, sign-up goes ahead and logs it. Set breachCheckFailsClosed: true to refuse instead.

Block paths by country

final DVWaf adminFirewall = DVWaf(
  const <DVWafRule>[
    DVWafRule(
      name: 'admin-from-office-countries',
      paths: <String>['/admin/**'],
      from: DVWafSource.notIn(<String>['NG', 'GB']),
    ),
  ],
  // Believed only when the request came through a trusted proxy.
  countryOf: DVWaf.countryHeader('cf-ipcountry'),
);

final MiddlewareChain edgeChain = MiddlewareChain()..use(adminFirewall.middleware());

Copy code to clipboard

The first rule that matches decides. A refusal is logged with DV-EDGE-003 and the rule's name.

A country header counts only from a proxy you trust. From anywhere else the country is unknown.

lint() lists rules that match everything, and rules that have matched nothing for 90 days.

Put a budget on GraphQL queries

# pubspec.yaml
dartvel:
  api:
    graphql:
      maxDepth: 8
      introspection: authenticated
      persistedQueries: prefer

Copy code to clipboard

Depth and cost budgets are on by default, worked out from your models. A query over budget is refused with DV-EDGE-001.

persistedQueries: require answers only queries in the manifest, with DV-EDGE-002 for the rest.

Trust your proxy for the client address

# pubspec.yaml
dartvel:
  server:
    trustedProxies: [10.0.0.0/8]
    forwardedHeader: x-forwarded-for
    ipv6SourcePrefix: 64

Copy code to clipboard

Forwarded headers are read only from a peer in trustedProxies. DARTVEL_TRUSTED_PROXIES sets the list at run time.

IPv6 clients are counted per /64 by default, so one host cannot dodge a limit by changing its address.

Status

Partial

Spec section: Edge Security

Planned work and implementation limits

The WAF is not a middleware key or a pubspec setting. You add it to a MiddlewareChain you run.

Sign-in counts are kept per process, and there is no firewall or captcha provider adapter.

Generated clients do not send persisted query hashes yet.

PREVIOUS Modules Mount apps, and wrap Dart, npm, C, Rust, JVM or Swift code
NEXT Secrets and environments Keys that stay on the server, checked at build and deploy
GitHub
pub.dev
npm
Acknowledgements
Privacy
Terms

FSL-1.1-MIT licensed. Built with Dartvel.

Dartvel is made by

SigmaDev Digital

To the bottom