One fluent API retrieves credentials whether typed directly, stored in a password manager vault, or obtained via an OAuth/service-account/API-key flow. The consuming code stays the same.
GPAL provides one consistent way to retrieve credentials regardless of where they live. Three families cover every case: direct values you supply inline, password manager vaults that look up saved logins by name or URL, and provider authentication that handles OAuth flows and API keys for cloud services and AI providers. Every family shares the same fluent interface and ends with the same two terminal calls -- one that builds a login row for a form, and one that returns a bearer token for an API call. The code that consumes the result never needs to know which source produced it.
Password manager vaults work in two different ways depending on the vault. Some rely on an installed command-line tool that must already be logged in; GPAL calls out to it and checks session status before searching. Others are accessed directly through a REST API using a key pair, with no external tool required. Either way, you search by item name, URL, or username and get back one login row per match. Provider authentication works differently: service accounts can authenticate directly with no browser step, while OAuth flows open a browser for one-time consent the first time. Save the token that comes back and supply it on later runs to skip that step. The result in both cases is a bearer token ready for an API call.
// Build a reusable master login once, as CredentialServiceType.None
var masterLogin = GPAL.CredentialsFor(CredentialServiceType.None)
.WithUsername("you@example.com")
.WithPassword("master-password")
.ToGPALObject();
// Vault lookup: reuse the master login, terminate with SaveTo
var loginGrid = GPAL.Grid.ToGPALObject();
GPAL.CredentialsFor(CredentialServiceType.LastPass)
.WithCredentials(masterLogin)
.GetCredentialsFor("example.com")
.WithDomain("example.com")
.SaveTo(loginGrid);
GPAL.Browser
.GoTo("https://example.com/login")
.WithSelector("#username")
.WithSelector("#password")
.FillInFrom(loginGrid)
.LeftClick("#login");
// OAuth/service-account: terminate with FetchAccessToken instead
GPAL.CredentialsFor(CredentialServiceType.Google)
.WithUsername("you@example.com")
.WithPassword("your-password")
.WithClientId("client-id.apps.googleusercontent.com")
.WithClientSecret("client-secret")
.WithRefreshToken("refresh-token") // skips the consent browser on repeat runs
.WithScope(OAuthScope.Google_Drive)
.FetchAccessToken(out string accessToken);
GPAL.RESTClient
.WithAPIBase("https://www.googleapis.com")
.WithEndpoint("/drive/v3/about?fields=user")
.WithHeader("Authorization", "Bearer " + accessToken)
.Execute();
Every credentials chain ends in SaveTo(grid) or FetchAccessToken(out token), determined entirely by CredentialServiceType. None and the vaults always use SaveTo, Google/Azure/AWS and the API-key services always use FetchAccessToken. Switching sources, say from a hardcoded None during development to a real vault or OAuth flow in production, only changes the WithService/GetCredentialsFor/WithScope setup; the terminal call and everything after it stays the same.
A config file backs the credential system with OAuth endpoints, redirect URIs, and vault API base URLs for each provider. If you need to customize those -- say, pointing a self-hosted Bitwarden instance at a different URL -- load the config, change the value, and save it back to disk for future runs. OAuth flows require one-time browser consent on the first run; save the refresh token that comes back and supply it on later runs to skip it. For AI provider keys that are just static strings, there is no OAuth flow at all -- the key goes in directly and FetchAccessToken hands it back as-is.
If a vault's command-line tool isn't installed or logged in, GPAL publishes an error event with the login command to run, and the lookup returns no rows -- leaving nothing to fill into a form. GPAL also doesn't check that a credential type matches its consuming provider. A mismatched key and provider will compile and run but fail with an authentication error at request time. Verify login status and key/provider pairing before relying on either in an unattended workflow.
Showing off some plain text in these paragraphs eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quo veniam mollitia excepturi animi eum illum non libero sapiente provident assumenda, delectus voluptatum nobis sed dolorem adipisci laudantium incidunt. Error, ratione?
Here you can find different accents and emphasis sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
This is a link and how it could look like bestlinkinthebeautifulworld. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Here's just some classic bold text adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam notBoldSecondbestlinkinthebeautifulworld illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at adipisicing elit libero vel voluptas? Expedita, adipisicing facere dolores voluptatem ad ab rem assumenda soluta!
Other cuple of colors in case we want to emphasize several ways adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam adipisicing elit illo nostrum corporis at voluptatem libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta! Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quod veniam, quam ad expedita laborum sed at voluptates culpa ipsam ut vel. Ullam temporibus a mollitia quod aliquam ratione exercitationem nesciunt.
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, iste distinctio veritatis eligendi laboriosam illo nostrum corporis at libero vel voluptas? Expedita, facere dolores voluptatem ad ab rem assumenda soluta!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repudiandae quas consequuntur illo numquam assumenda autem exercitationem distinctio perspiciatis in natus. Eius dicta similique ipsam ipsa minima, nemo quae enim tempore.
GPAL
.CallIfNotFound(GenericCallIfNotFound)
.WithPublishToConsole();
//System.Drawing.Rectangle windowSize = new System.Drawing.Rectangle(10, 10, 1500, 1024);
// NOTE: we have to set browser = before we execute any steps
// this is due to the 'GenericCallIfNotFound' which might throw an exception, and BankScraper will not have the browser set when it calls scraper.Close()
// until the complete fluent line gets executed (meaning every step, meaning browser is not set until everything else succeeds)
browser = GPAL.Browser
.WithBrowserType(Enums.BrowserType.Chrome)
.WithProfileDataDirectory(ChromeProfileLocation)
.WithUseAutomationEngine(AutomationEngine.Selenium)
.WithWindowSize(new System.Drawing.Rectangle(0,0,1920,1080))
.ToGPALObject();