Static outbound IPs for selected Laravel Cloud API calls

Keep your application on Laravel Cloud while giving an IP-restricted API a small, stable set of source addresses. Configure one Laravel HTTP client for that integration, keep its credentials in the correct Cloud environment, and check the route from the code paths that actually send requests.

The practical benefit is a focused networking change. Your API integration can use QuotaGuard while unrelated HTTP calls, browser traffic, and database connections keep their existing paths. The same client can be reused by controllers, queued jobs, and scheduled tasks.

Choose the route that fits the provider

Laravel Cloud already offers a native starting point: its network documentation publishes regional outbound addresses and links a machine-readable IP API. Those addresses can change. If the destination accepts the regional set and your team can maintain it, that may meet your needs without a proxy. Dedicated Private Cloud compute has separate onboarding addresses.

QuotaGuard is useful when selected requests should use an assigned IPv4 pair instead of maintaining the Cloud regional list. Discuss the destination’s accepted source region and shared or dedicated address requirements before provisioning. An assigned shared address is not an account-exclusive address. See shared and dedicated proxies.

Use the destination’s HTTPS hostname, not a hard-coded destination IP. The addresses you register on its allowlist are the source addresses it should observe. Your website’s inbound address and an end user’s IP are separate from that source identity.

How the request travels

Laravel controller or job
    selected QuotaGuardHttp client
    QuotaGuard proxy connection
    one of the assigned IPv4 addresses
    destination HTTPS API

Other HTTP client calls and database connections
    their existing routes

This is application-level selection, not an environment-wide egress firewall. An SDK that creates its own HTTP transport must be configured independently or replaced with a supported injectable client.

Prepare the connection settings

Open Setup → Outbound Proxy → Connection Information in the intended QuotaGuard subscription. Retain the complete HTTP proxy URL and both assigned IPv4 addresses. Use the actual dashboard hostname and port. Do not substitute an example region or one of the source IPs as the proxy hostname. The connection-details guide identifies these values.

Register both assigned addresses with the API provider. Traffic can use either address, so a successful request through one does not make the other optional. Why two addresses are provided explains this behavior. Confirm the destination is reachable over IPv4 and accepts the selected arrangement.

The reference factory uses QuotaGuard Static with an HTTP proxy URL. For HTTPS destinations, the destination TLS session travels through CONNECT. The initial application-to-proxy connection and proxy authentication do not gain TLS merely because the destination URL starts with https://. If that extra hop must also be encrypted, use a separately reviewed Shield configuration supported by the deployed client. See how HTTPS proxying works.

Configure Laravel Cloud secrets

Store the full connection URL as QUOTAGUARDSTATIC_URL. Keep it server-side and out of Git, browser bundles, error responses, screenshots, and logs.

Cloud organization secrets must be linked to the target environment. Check for a custom environment variable with the same name, because that value takes precedence over the linked secret. Redeploy when a secret or environment value changes. These are part of Cloud’s secret behavior, not special QuotaGuard requirements.

Keep staging and production settings separate. Record which subscription, pair, environment, and provider allowlist belong together without recording the full credential-bearing URL. A preview environment should not silently inherit production access merely because the configuration key has the same name.

Read environment variables through a configuration file

Add the unchanged reference file code/config/quotaguard.php to config/quotaguard.php in the application:

<?php

return [
    'proxy_url' => env('QUOTAGUARDSTATIC_URL'),
];

Application code should read config('quotaguard.proxy_url'), not call env() inside a controller or job. Laravel configuration caching changes when .env is read. Cloud recommends caching generated configuration during the build step, so those files are part of the deployment.

Retain the application’s existing build steps. Do not replace the build command with a tutorial fragment. Include the existing php artisan optimize or agreed configuration-caching step at the appropriate point. Avoid adding a second, conflicting cache command as a troubleshooting shortcut.

Add the selected client factory

Copy code/app/Support/QuotaGuardHttp.php to the matching application path. The original factory is included verbatim:

<?php

namespace App\Support;

use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;
use RuntimeException;

final class QuotaGuardHttp
{
    public static function client(): PendingRequest
    {
        $proxy = config('quotaguard.proxy_url');

        if (! is_string($proxy) || trim($proxy) === '') {
            throw new RuntimeException('QuotaGuard proxy is not configured.');
        }

        if (! extension_loaded('curl')) {
            throw new RuntimeException('This client requires the PHP cURL extension.');
        }

        return Http::withOptions([
            'proxy' => trim($proxy),
            'curl' => [CURLOPT_NOPROXY => ''],
            'allow_redirects' => false,
        ])->connectTimeout(10)->timeout(30);
    }
}

The factory configures Guzzle request options through Laravel. It stops before a request if the proxy setting is missing, requires cURL, sets bounded timeouts, and disables automatic redirects. It leaves normal certificate and hostname verification enabled.

The empty CURLOPT_NOPROXY is specific to the cURL handle. It prevents an ambient bypass list from skipping this selected proxy. It assumes the standard Guzzle cURL handler; a custom handler needs separate validation. See libcurl’s option contract.

This compact factory does not validate every possible proxy URL format or prevent a later caller from changing its options. Keep configuration trusted, copy the exact connection URL, and do not append request options that replace the proxy. A missing-secret guard is not a general egress enforcement layer.

Connect the actual integration

Locate the precise request constructor used by the protected API integration. If it currently starts with Http::, create that request from QuotaGuardHttp::client() instead. Preserve the provider’s existing authentication, URL, headers, payload, response handling, and transaction behavior.

For example, a read-only integration service can receive the configured request object and add only the authentication and fixed endpoint its provider requires. Do not attach provider credentials to the IP echo service. Do not accept an arbitrary caller-supplied URL and forward it through the proxy.

If an SDK owns the transport, inspect its documented client or handler injection points. An environment variable does not prove that the SDK uses it. Avoid global HTTP_PROXY or HTTPS_PROXY changes as a substitute for understanding which library sends the request.

Do not add direct fallback after a proxy error. It can expose an unapproved source address and hide a routing problem behind occasional success. For state-changing provider requests, retries also need the provider’s idempotency and reconciliation rules; a network timeout alone does not establish that the provider did no work.

Verify the deployed command route

Merge code/routes/console-snippet.php into the application’s existing routes/console.php. Keep other commands, avoid duplicate imports, and retain only one PHP opening tag. The command sends a GET to https://ip.quotaguard.com through the selected factory, reads the JSON ip field, validates IPv4, and prints only that value.

Run the command through the deployed environment’s Commands tab:

php artisan quotaguard:check

A zero exit status means the command received a successful response with a valid IPv4 value. You must still compare that value with the subscription’s assigned pair. An unrelated but syntactically valid IPv4 address is not a successful route check.

For an automatic pair comparison, use the additional QuotaGuardEgressProbe example described in Runtime examples. It requires both expected addresses before any request and rejects any other observed value.

Cloud can run one-time commands on any available instance. This is a useful deployed check, not coverage of every application path.

Verify web and worker paths separately

Create a short inventory of every path that calls the protected API: an authenticated web action, queue job, scheduled task, webhook-triggered background handler, or independent SDK. Mark which client each path constructs.

Use the same selected factory in the real integration path. Run a harmless provider-approved request using the appropriate account and environment. When available, correlate the result with destination-side request logs or a provider request identifier. The echo connection and provider connection are different connections and may use different members of the assigned pair.

Cloud worker clusters share code, runtime, and variables with the environment, but code still determines the transport. A queue job that creates a different client can bypass the factory even when its secrets are correct. Verify a real queued execution rather than substituting a synchronous call from an interactive shell.

Repeat for scheduled work if it has a separate integration path. Keep a private record of the release identifier, environment, execution path, expected pair, observed echo IP, and provider response status. Do not retain response bodies or credentials just to prove routing.

Know when the setup is ready

Use these acceptance criteria for the specific integration:

  • The provider has accepted both assigned source IPs and the selected region and ownership arrangement.
  • The intended deployment has the correct secret linkage and no stale override.
  • The configuration-caching build retains the intended value without exposing it.
  • The actual HTTP transport retains the proxy and does not disable TLS verification.
  • The deployed command and each relevant web, worker, and scheduled path use the expected route.
  • Provider authentication and the harmless request succeed independently of the echo result.
  • Missing configuration and connection failures do not trigger a direct retry.

Keep the operational details in the rotation and release runbook. For general PHP setup, use the existing PHP quick start; this guide adds the Laravel Cloud deployment and execution-path details.

Download the reference examples · Integration overview


Ready to Get Started?

Get in touch or create a free trial account

Back to top ↑

Copyright © 2009 - 2026 QuotaGuard. All rights reserved.