$user->credentials = $user->credentials->changePassword("newPassword");
That's the right idea.
In this implementation, $username and $password are part of the state of Credentials. You want that state to be immutable; there should be no code that changes that state after the constructor has finished.
However, you need to expose that state somehow; immutable write-only objects don't provide very much business value. Implementing value types as a collection of immutable public properties is a common idiom. Here's an old discussion of how to do that in PHP. Alternatively, you can implement calls that allow the Credentials object to pass copies of that state to other objects.
Should I create a getter and a setter for the $credentials property of my User class ?
Not usually -- your implementation of User has an Id property, which makes it look like an entity. Entities only very rarely allow their internal state to escape. In particular, setters are many nines close to never a good idea -- the point of entities is that they can enforce their own data constraints; they are responsible for ensuring that all changes to their state satisfy the business invariant.
A getter that offers access to immutable state isn't likely to cause problems; a getter that allows the caller to navigate to mutable state is worrisome.
BUT: getters aren't particularly expressive -- a query, possibly supported by a domain service, is often a more flexible choice
Compare:
password = user.password
strength = calulatatePasswordStrength(password.toString)
to
password = user.password
strength = password.strength(calculator)
to
strength = user.passwordStrength(calculator)
Should I put the changePassword() method in the User class ?
Assuming that you are supporting that use case, yes. The Credentials value knows how to calculate a new state of credentials from an old one; the User entity knows how to validate that the user in its current state is allowed to change the credentials in that way.
(Example: a naive security implementation might track when the credentials were last changed, and have policies that restrict password changes, where the correct policy to use depends on other properties of the user. That's way too much work for the credentials object to be doing on its own.)
In particular, the fact that the user's password is actually a bunch of state in a Credentials value object is an implementation detail, which shouldn't be exposed to the code that calls User. In other words, if User were implementing the interface IUser (isolating the implementation details), then I would expect IUser to promise that a changePassword($password) method will be available.