# The cf CLI speaks the v3 Cloud Controller API, and its Windows shell problems are documented rather than fixed

> cloudfoundry/cli is the official Go client for Cloud Foundry, backed by the v3 Cloud Controller API in v8, with an external plugin API and a long, specific list of known issues. The v7 and v6 lines are no longer maintained or released.

**cloudfoundry/cli** — The official command line client for Cloud Foundry

- Repository: https://github.com/cloudfoundry/cli
- Website: https://docs.cloudfoundry.org/cf-cli
- Stars: 1,939 · Forks: 986
- Language: Go
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/cloudfoundry-cli

## One maintained line, and it maps to the v3 API

The README is unambiguous about support. The v8 cf CLI is backed by the v3 CC API, with the exception of plugins, and the note underneath says v7 and v6 CLI versions are no longer maintained or released. The Versioning and Support Policy wiki page is the reference for the schedule.

That means the version choice is effectively made for you. If your foundation exposes only v2, the CLI that speaks it is the old one, and the old one is frozen.

Help is versioned the same way. The README links separate documentation for the v8 CLI and the v7 CLI, and points at cf help -a for the commands available in whichever version is actually installed, which is the check to run first when behaviour differs between your machine and a colleague's.

The implementation is Go, with the module declared as code.cloudfoundry.org/cli/v9 and go 1.26.9 in go.mod. That mismatch between the v9 module path and the v8.19.0 release tag is worth noting: the source tree is ahead of the shipped binary line, so the module path alone does not tell you which API generation the code targets.

## Installing means following the wiki, since the README has no installer commands

The README does not contain installation steps. It links a V8 CLI Installation Guide wiki page for the current version, a V7 guide marked DEPRECATED and no longer maintained, and a version switching guide for moving between multiple installed versions on one machine.

Two things follow. First, you cannot deploy the CLI from this repository alone; the download lives on the project's downloads section, and the README points there for the v8 build. Second, the version switching guide implies that having more than one major version installed at once is a supported state, which is what makes an upgrade survivable in an environment with automation pinned to the old one.

Help output is browsable online through the command help pages site linked in the badges, so you can check whether a command exists in your version before running it.

## The known issues list is the most useful part of the README

Most READMEs treat known issues as an afterthought. This one enumerates them, and several describe failures that look like bugs in your environment.

The Windows shell entries are the densest cluster. In Cygwin and Git Bash, interactive password prompts in cf login do not hide the password from stdout, which is issue 1835; the stated workarounds are to use the non-interactive cf auth command instead of cf login, or to use the Windows cmd command line. cf ssh may not display correctly on Windows when TERM is unset, and setting TERM to msys fixes some of it. cf ssh hangs when run from MINGW32 or MINGW64, and the workaround is PowerShell.

That last one deserves emphasis: a hang in cf ssh from a Git Bash shell is documented behaviour with a documented fix, not a bug you need to debug.

The TLS entry is the one most likely to affect an internal deployment. CF CLI and Go do not use OpenSSL, so custom or self signed certificates have to be installed in specific locations before login or auth will work without --skip-ssl-validation. That is a different trust store model from the rest of the toolchain on the machine.

Trace output has its own caveat. API tracing to the terminal through CF_TRACE=true, the -v option or cf config --trace does not work well with some plugin commands, while tracing to a file is fine. On Linux, CF_TRACE=/dev/stdout also works. Warnings go to stdout, and setting CF_RAISE_ERROR_ON_WARNINGS moves them to stderr, which matters if a script parses one stream.

One encoding trap: .cfignore used by cf push must be in UTF-8 for the CLI to interpret it correctly, which is issue 281.

## Plugins get their own import path, and old ones keep working

Extension goes through a plugins API, with a plugin development guide in the plugin/plugin_examples directory of the repository and a plugins repository hosted separately.

The import path is the detail that breaks builds. The README says to import "code.cloudfoundry.org/cli/v9/plugin" when importing plugin code. Older plugins that import github.com/cloudfoundry/cli/plugin still work, as long as they vendor the plugins directory.

That compatibility note is a migration path rather than a promise: it depends on vendoring, which means a plugin written for the old path is carrying a copy of the interface rather than tracking the current one. Plugins also sit outside the v3 API commitment, since the README notes that v8 is backed by v3 with the exception of plugins. 

There is also a community plugin list linked from the README, and the Diego-Enabler plugin is named as an example of a plugin whose terminal tracing misbehaves.

## Building from source, where the Makefile's own version constant is a TODO

Building runs through the Makefile, whose default target is lint, test and build in sequence. The build target compiles a cf binary into out/.

The version stamping is where the source tree shows its unfinished business. CF_BUILD_VERSION defaults to v9.0.0, with a comment reading TODO: Change when new version is released, and the alternative line that would derive it from git describe --tags is commented out. The SHA and build date come from git rev-parse and a UTC date, and all three are injected through ldflags into the version package as binaryVersion, binarySHA and binaryBuildDate.

That is why building from main produces a binary that reports a version you did not choose. If you build rather than download, the reported version is a Makefile constant until someone edits it.

The test setup is Ginkgo and Gomega based. The Makefile defines unit and integration targets with -randomize-all and -randomize-suites flags, a suite timeout of two hours, a poll progress threshold of 120 seconds, and a variable that sets NODES to 10 and FLAKE_ATTEMPTS to 5. Integration runs require CF_INT_API and CF_INT_PASSWORD, and the target errors out if either is undefined, which is a clean way to avoid running an integration suite against the wrong foundation.

## Reporting problems and where support actually lives

The README's issue guidance is a two step process: update to the latest CLI and try the command again, then check the open issues, and only file a new one if it has not been raised.

That ordering assumes you can install a new release, which is one more reason the download path matters.

Questions go to the #cli channel on the project's Slack, the cf-dev mailing list, or a GitHub issue. Translation updates have their own path, through the i18n README under cf/i18n, rather than through general pull requests.

The repository layout shows the shape of the codebase: command/ holds the command implementations, api/ the Cloud Controller client, actor/ the orchestration layer above it, types/ for the data model, util/ for helpers, plugin/ for the plugin API, integration/ for the end to end suite, and doc/, strings/ and resources/ for the user facing surface.

Licensing is Apache 2.0, in the LICENSE file at the root with a NOTICE alongside.

## The alternative: talking to the API directly

The difference in approach is where the abstraction sits. cf puts a command vocabulary, a configuration file, an SSH command and a plugin model on top of the API, and it keeps that vocabulary stable across foundation versions. A direct client puts the API version in your code and leaves you to handle authentication, pagination and error shapes yourself.

 The direct client wins when you want no local configuration on the build agent and you can pin the API version yourself.

The historical v2 behaviour is the deciding factor in a lot of cases, and the README's note that v7 and v6 are no longer maintained or released means there is no maintained client for a v2 only foundation.

## Conclusion

Adopt the v8 cf CLI if you deploy to Cloud Foundry today, since it is the only maintained line and it tracks the v3 API, and rely on plugins for anything the core commands do not cover. Do not adopt it if your platform still exposes only the v2 API, since the README records that v7 and v6 are no longer maintained or released. Verify first which major version you are scripting against, because the Go module path in this repository is code.cloudfoundry.org/cli/v9 while the newest tagged release listed is v8.19.0, and check the shell you run it from on Windows before debugging a hang.

## FAQ

### Which version of the cf CLI is still supported?

The v8 CLI, which is backed by the v3 Cloud Controller API with the exception of plugins. The README states that v7 and v6 CLI versions are no longer maintained or released, and points to the Versioning and Support Policy wiki page.

### Why does cf login not hide my password in Git Bash?

This is a documented Windows issue, tracked as issue 1835: interactive password prompts in cf login do not hide the password from stdout in Cygwin and Git Bash. The stated workarounds are to use the non-interactive cf auth command instead of cf login, or to use the Windows cmd command line.

### How do I use cf with a self signed certificate?

The CLI and Go do not use OpenSSL, so custom and self signed certificates must be installed in specific locations for login or auth to succeed without --skip-ssl-validation. The README links the project's documentation page on self signed certificates.

### What import path do Cloud Foundry CLI plugins use?

New plugin code should import "code.cloudfoundry.org/cli/v9/plugin". Older plugins importing github.com/cloudfoundry/cli/plugin still work provided they vendor the plugins directory.

### How do I get API tracing out of the cf CLI?

Tracing to the terminal through CF_TRACE=true, the -v option or cf config --trace does not work well with some plugin commands, while tracing to a file works. On Linux, CF_TRACE=/dev/stdout also works, and CF_RAISE_ERROR_ON_WARNINGS sends warnings to stderr instead of stdout.

## Sources

- [cloudfoundry/cli on GitHub](https://github.com/cloudfoundry/cli)
- [License: Apache-2.0](https://github.com/cloudfoundry/cli/blob/main/LICENSE)
- [Project website](https://docs.cloudfoundry.org/cf-cli)
- [README](https://github.com/cloudfoundry/cli/blob/main/README.md)
- [Releases](https://github.com/cloudfoundry/cli/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/cloudfoundry-cli
